Korrekte Überprüfung auf DBNull

  • VB.NET
  • .NET (FX) 4.5–4.8

Es gibt 13 Antworten in diesem Thema. Der letzte Beitrag () ist von Niko Ortner.

    Korrekte Überprüfung auf DBNull

    Moin!

    Ich lese aus einer MySQL Datenbank. Gelegentlich ist der Inhalt NULL, was meinen Reader aus den Fugen haut.

    VB.NET-Quellcode

    1. ​While rdr.Read
    2. 'MsgBox(rdr(0).GetType.ToString)
    3. If rdr.HasRows And rdr(0).GetType IsNot DBNull.Value Then
    4. Dim byteData() As Byte = rdr(0)
    5. ergebnis = DecompressASCII(byteData)
    6. ElseIf rdr(0).GetType Is DBNull.Value Then
    7. ergebnis = "Leere Datei!"
    8. End If
    9. End While


    Ich dachte ich hätte mit rdr(0).GetType IsNot DBNull.Value schon genug vorgesorgt, aber das Problem besteht weiterhin...

    Könnt Ihr mich aufklären, wo mein Fehler liegt?
    Die Fehlermeldung sagt, dass das ankommende Object vom Typ System.DBNull ist. Du überprüfst jedoch, ob der Type System.DBNull.Value ist.
    Versuch es mal mit

    VB.NET-Quellcode

    1. If rdr.HasRows And rdr(0).GetType IsNot DBNull Then


    Ich persönlich würde mir mal Convert.IsDBNull() anschauen.

    LG Acr0most
    Wenn das Leben wirklich nur aus Nullen und Einsen besteht, dann laufen sicherlich genügen Nullen frei herum. :D
    Signature-Move 8o
    kein Problem mit privaten Konversationen zu Thema XY :thumbup:
    Man prüft, ob ein Ausdruck x einen Typ T hat, so: If TypeOf x Is T Then, bzw. negiert: If Not TypeOf x Is T Then (hier funktioniert "IsNot" nicht).
    Also:

    VB.NET-Quellcode

    1. If rdr.HasRows AndAlso Not TypeOf rdr(0) Is DBNull Then


    Nebenbei:
    If rdr(0).GetType Is DBNull.Value Then kann nicht funktionieren.
    rdr(0).GetType gibt eine Instanz von System.Type zurück, System.DBNull.Value ist aber vom Typ System.DBNull. Du vergleichst also Äpfel mit Birnen.
    Wenn, dann so: If rdr(0).GetType = GetType(DBNull) Then, aber dafür gibt es keinen guten Grund. Das geht übrigens auch in die Hose, wenn rdr(0) tatsächlich mal Nothing ist.

    Nebenbeier:
    rdr(0) Is DbNull.Value funktioniert dann und nur dann korrekt, wenn es tatsächlich nur eine einzige Instanz der DBNull-Klasse geben kann und diese Instanz DBNull.Value ist. Das sollte eigentlich der Fall sein, aber ich würde mich nicht drauf verlassen.
    "Luckily luh... luckily it wasn't poi-"
    -- Brady in Wonderland, 23. Februar 2015, 1:56
    Desktop Pinner | ApplicationSettings | OnUtils
    Lt. Source existiert nur eine Instanz von DBNull, da der Konstruktur Private ist und es nur eine Statische Variable Value gibt.

    C#-Quellcode

    1. /// <summary>Stellt die einzige Instanz der <see cref="T:System.DBNull" />-Klasse dar.</summary>
    2. /// <filterpriority>1</filterpriority>
    3. public static readonly DBNull Value = new DBNull();
    4. private DBNull()
    5. {
    6. }


    lg
    ScheduleLib 0.0.1.0
    Kleine Lib zum Anlaufen von Code zu bestimmten Zeiten
    @fichz
    Ja, das habe ich auch gesehen, aber da die Klasse ISerializable implementiert, sind bei mir die Alarmglocken losgegangen.

    ...

    Ein Gegenbeispiel zu finden war sogar noch einfacher, als ich es erwartet habe:

    VB.NET-Quellcode

    1. Dim a As DBNull = DBNull.Value
    2. Dim b As DBNull = DirectCast(Activator.CreateInstance(GetType(DBNull), True), DBNull)
    3. Dim ok = a Is b


    (DirectCast(GetType(DBNull).GetConstructor(Reflection.BindingFlags.NonPublic Or Reflection.BindingFlags.Instance, Nothing, Type.EmptyTypes, Nothing).Invoke(Nothing), DBNull) funktioniert übrigens auch.)
    "Luckily luh... luckily it wasn't poi-"
    -- Brady in Wonderland, 23. Februar 2015, 1:56
    Desktop Pinner | ApplicationSettings | OnUtils
    Jou.
    @pascalts Wenn Du wissen willst, ob ein DB-Wert auslesbar ist, darf er nicht DbNull.Value sein. Mit nem Type hat das gar nix zu tun.

    VB.NET-Quellcode

    1. If rdr.HasRows AndAlso rdr(0) <> DBNull.Value Then
    2. ' ...
    3. End If

    Falls Du diesen Code kopierst, achte auf die C&P-Bremse.
    Jede einzelne Zeile Deines Programms, die Du nicht explizit getestet hast, ist falsch :!:
    Ein guter .NET-Snippetkonverter (der ist verfügbar).
    Programmierfragen über PN / Konversation werden ignoriert!
    korrekter wäre

    VB.NET-Quellcode

    1. If not rdr.IsDbNull(0) Then
    2. '...
    So braucht niemand zu überlegen, was mit Convert.DbNull ist, Convert.IsDbNull, DbNull.Value und wasses so alles gibt.
    Weil der Reader weisses ja selbst.

    Die Abfrage auf .HasRows ist quatsch - im Zusammenhang mit Post#1 gesehen.
    Weil Wenn ein Reader readed, dann has er auch Rows, sonst readet er ja nicht.
    deshalb:

    MSDN schrieb:


    Anforderungen
    Namespace:Microsoft.VisualBasic

    Der sollte soweit wie möglich vermieden werden, weil er in erster Linie für VB6-Kompatibilität noch exisitiert. Solange man ein Problem mit VB.Net-Möglichkeiten lösen kann, sollte man dies auch tun.
    Dieser Beitrag wurde bereits 5 mal editiert, zuletzt von „VaporiZed“, mal wieder aus Grammatikgründen.

    Aufgrund spontaner Selbsteintrübung sind all meine Glaskugeln beim Hersteller. Lasst mich daher bitte nicht den Spekulatiusbackmodus wechseln.
    @7081
    Funktionieren tut's schon, macht aber intern auch nur das:

    VB.NET-Quellcode

    1. Public Shared Function IsDBNull(Expression As Object) As Boolean
    2. Return Expression IsNot Nothing AndAlso TypeOf Expression Is DBNull
    3. End Function

    Warum da nochmal auf Nothing geprüft wird, erschließt sich mir nicht, da TypeOf Nothing Is DBNull sowieso False zurückgibt, also einfach nur TypeOf Expression Is DBNull tut's auch.
    "Luckily luh... luckily it wasn't poi-"
    -- Brady in Wonderland, 23. Februar 2015, 1:56
    Desktop Pinner | ApplicationSettings | OnUtils

    Dieser Beitrag wurde bereits 1 mal editiert, zuletzt von „Niko Ortner“ ()