2008-08-15 14 views
13

Mamy własną ORM, której używamy tutaj, i dostarczamy silnie typowane opakowania dla wszystkich naszych tabel db. Pozwalamy również na wykonanie słabo wpisywanego SQL ad-hoc, ale zapytania te nadal przechodzą przez tę samą klasę, aby uzyskać wartości z czytnika danych.C# Dostęp do bazy danych: DBNull kontra null

Podczas ulepszania tej klasy do pracy z Oracle natknęliśmy się na interesujące pytanie. Czy lepiej jest użyć DBNull.Value, lub null? Czy są jakieś korzyści z używania DBNull.Value? Wydaje się, że bardziej "poprawne" jest użycie wartości null, ponieważ oddzieliliśmy się od świata DB, ale są implikacje (nie można po prostu ślepo ToString(), gdy wartość jest na przykład pusta), więc jest to zdecydowanie coś, co musimy zrobić, aby świadoma decyzja o.

Odpowiedz

15

Uważam, że lepiej używać wartości NULL, zamiast DB null.

Powód jest taki, ponieważ, jak powiedziałeś, oddzielasz się od świata DB.

Dobrą praktyką jest sprawdzanie typów referencji, aby upewnić się, że nie są one puste. Będziesz sprawdzał wartość zerową w przypadku danych innych niż DB i uważam, że najlepiej jest zachować spójność w całym systemie i używać wartości null, a nie DBNull.

W dłuższej perspektywie, architektonicznie uważam, że jest lepszym rozwiązaniem.

3

Z mojego doświadczenia wynika, że ​​.NET DataTables i TableAdapters działają lepiej z DBNull. Otwiera również kilka specjalnych metod, gdy są silnie wpisane, takie jak DataRow.IsFirstNameNull, gdy są na miejscu.

Żałuję, że nie mogę dać ci lepszej odpowiedzi technicznej, ale dla mnie podstawą jest użycie DBNull podczas pracy z obiektami powiązanymi z bazą danych, a następnie użycie "standardowej" wartości zerowej, gdy mam do czynienia z obiektami i. Kod związany z NET.

1

Użyj DBNull.
Zaatakowaliśmy pewne problemy podczas używania wartości null.
Jeśli poprawnie przywołuję, nie można wstawić wartości zerowej do pola, tylko DBNull.
Może to być tylko związane z Oracle, przepraszam, nie znam już szczegółów.

7

Jeśli napisałeś własną ORM-a, to powiedziałabym, że po prostu użyjesz wartości NULL, ponieważ możesz jej użyć tak, jak chcesz. Wierzę, że DBNull był pierwotnie używany tylko po to, aby ominąć fakt, że typy wartości (int, DateTime, itd.) Nie mogą być być null, więc zamiast zwracać pewną wartość, jak zero lub DateTime.Min, co oznaczałoby implikuje a wartość null (złe, złe), stworzyli DBNull, aby to zaznaczyć. Może było w tym coś więcej, ale zawsze zakładałem, że to był powód. Jednak teraz, gdy mamy typy zerowalne w C# 3.0, DBNull nie jest już potrzebny. W rzeczywistości LINQ do SQL po prostu używa wartości null w każdym miejscu. Żaden problem. Obejmuj przyszłość ... użyj wartości null. ;-)

+0

Myślę, że nadal istnieją pewne zastosowania dla DBNull. Przynajmniej z sqlite mogę przetestować, czy wartość zwrócona przez ExecuteScalar() jest jawnie przechowywana w bazie danych, czy też nie. Rozważ tabelę foo (int, b int); z pojedynczym wierszem (1, null). Gdybyśmy wykonywali ExecuteScalar w poleceniu "SELECT b FROM foo WHERE A = 1", zwróciliby DBNull.Value (wiersz istnieje, a przechowywana jest wartość pusta). Gdybym zadzwonił do ExecuteScalar na "SELECT b FROM foo WHERE A = 2", zwróciłby on wartość null (żaden taki wiersz nie istnieje). Prawdopodobnie można osiągnąć ten sam wynik z DataReaderem, ale doceniam wygodę. – fostandy

+0

Interesujące. Korzystając z ORM dla dostępu do bazy danych, nie często jawnie używam ExecuteScalar w moim kodzie. Zwykle kończę pobieranie pełnych obiektów i patrzenie na ich wartości w ten sposób. Jeśli więc sama jednostka ma wartość zerową, to jedna rzecz, a jeśli wartość jest zerowa, to jest coś innego. Po prostu różne sposoby robienia tego.Przyznaję, że ExecuteScalar jest bardziej wydajny, jeśli potrzebujesz tylko jednej wartości. – jeremcc