2008-08-15 11 views
13

Wir haben unser eigenes ORM, das wir hier verwenden, und stellen stark typisierte Wrapper für alle unsere db-Tabellen bereit. Wir erlauben auch die Ausführung von schwach typisiertem Ad-hoc-SQL, aber diese Abfragen durchlaufen immer noch dieselbe Klasse, um Werte aus einem Datenleser zu holen.C# -Datenbankzugriff: DBNull vs null

Bei der Optimierung dieser Klasse mit Oracle haben wir eine interessante Frage gestellt. Ist es besser, DBNull.Value oder null zu verwenden? Gibt es Vorteile bei der Verwendung von DBNull.Value? Es scheint "richtiger" zu sein, null zu verwenden, da wir uns von der DB-Welt getrennt haben, aber es gibt Implikationen (Sie können nicht einfach blind ToString(), wenn ein Wert null ist), also ist es definitiv etwas, was wir machen müssen bewusste Entscheidung über.

Antwort

15

Ich finde es besser, null statt DB null zu verwenden.

Der Grund ist, weil, wie Sie sagten, Sie sich von der DB Welt trennen.

Es ist allgemein üblich, Referenztypen zu überprüfen, um sicherzustellen, dass sie nicht null sind. Sie werden für andere Dinge als DB-Daten auf Null prüfen, und ich finde es am besten, Konsistenz über das System zu halten, und verwenden Sie null, nicht DBNull.

Auf lange Sicht, architektonisch finde ich es die bessere Lösung.

3

Aus der Erfahrung, die ich hatte, arbeiten die .NET DataTables und TableAdapters besser mit DBNull. Es öffnet auch ein paar spezielle Methoden, wenn stark typisiert, wie DataRow.IsFirstNameNull, wenn vorhanden.

Ich wünschte, ich könnte Ihnen eine bessere technische Antwort als das geben, aber für mich ist das Endergebnis DBNull beim Arbeiten mit der Datenbank verwandten Objekte verwenden und verwenden Sie dann eine "Standard" Null, wenn ich mit Objekten und. NET bezogener Code.

1

Verwenden Sie DBNull.
Wir haben einige Probleme bei der Verwendung von null festgestellt.
Wenn ich mich richtig erinnere, können Sie keinen Nullwert in ein Feld einfügen, nur DBNull.
Könnte nur Oracle sein, sorry, ich kenne die Details nicht mehr.

7

Wenn Sie Ihren eigenen ORM geschrieben haben, dann würde ich sagen, verwenden Sie einfach null, da Sie es verwenden können, wie Sie wollen. Ich glaube, dass DBNull ursprünglich nur verwendet wurde, um die Tatsache zu umgehen, dass Werttypen (int, DateTime, etc.) null sein konnten, also eher als einen Wert wie null oder DateTime.Min zurückgeben, was bedeuten würde ein Null (schlecht, schlecht), sie haben DBNull erstellt, um dies anzuzeigen. Vielleicht gab es mehr, aber ich nahm immer an, dass das der Grund war. Jetzt, da wir in C# 3.0 NULL-fähige Typen haben, ist DBNull nicht mehr erforderlich. In der Tat verwendet LINQ to SQL überall nur Null. Überhaupt kein Problem. Umarme die Zukunft ... benutze null. ;-)

+0

Ich denke, es gibt noch einige Anwendungen für DBNull. Zumindest kann ich mit sqlite testen, ob ein von ExecuteScalar() zurückgegebener Wert explizit in der Datenbank gespeichert ist oder nicht. Betrachte Tabelle foo (a int, b int); mit einer einzigen Zeile (1, null). Wenn wir ExecuteScalar für einen Befehl "SELECT b FROM foo WHERE A = 1" verwenden, würde DBNull.Value zurückgegeben (die Zeile existiert, es wird eine Null gespeichert). Wenn ich ExecuteScalar auf "SELECT b FROM foo WHERE A = 2" aufrufen würde, würde es null zurückgeben (keine solche Zeile existiert). Vermutlich könnten Sie mit einem DataReader das gleiche Ergebnis erzielen, aber ich schätze den Komfort. – fostandy

+0

Interessant. Bei der Verwendung eines ORM für den DB-Zugriff verwende ich ExecuteScalar in meinem Code nicht oft explizit. Gewöhnlich lande ich am Ende vollständige Entitätsobjekte und schaue ihre Werte auf diese Weise an. Wenn also die Entity selbst null ist, ist das eine Sache, und wenn der Wert null ist, ist das etwas anderes. Nur verschiedene Möglichkeiten, es zu tun.Ich gebe zu, dass ExecuteScalar effizienter ist, wenn Sie nur einen einzigen Wert benötigen. – jeremcc