Otrzymałem powyższy błąd w mojej aplikacji. Oto oryginalny kod
public string GetCustomerNumber(Guid id)
{
string accountNumber =
(string)DBSqlHelperFactory.ExecuteScalar(connectionStringSplendidmyApp,
CommandType.StoredProcedure,
"GetCustomerNumber",
new SqlParameter("@id", id));
return accountNumber.ToString();
}
Zastąpiłem
public string GetCustomerNumber(Guid id)
{
object accountNumber =
(object)DBSqlHelperFactory.ExecuteScalar(connectionStringSplendidCRM,
CommandType.StoredProcedure,
"spx_GetCustomerNumber",
new SqlParameter("@id", id));
if (accountNumber is System.DBNull)
{
return string.Empty;
}
else
{
return accountNumber.ToString();
}
}
Czy jest lepszy sposób obejścia tego?
Odpowiedzi:
Można użyć krótszej formy:
EDYCJA: Nie zwróciłem uwagi na ExecuteScalar. W rzeczywistości zwraca wartość null, jeśli w wyniku zwracanym nie ma pola. Zamiast tego użyj:
źródło
null
, jeśli wybrany wiersz maNULL
w tej kolumnie, wartość zwracana toSystem.DBNull
.Dzięki prostej funkcji ogólnej możesz to bardzo ułatwić. Po prostu zrób to:
za pomocą funkcji:
źródło
ExecuteScalar zwróci
Jeśli wiesz, że pierwsza kolumna zestawu wyników jest łańcuchem, to aby objąć wszystkie zasady, musisz sprawdzić zarówno null, jak i DBNull. Coś jak:
Powyższy kod opiera się na fakcie, że DBNull.ToString zwraca pusty ciąg.
Gdyby numer konta był innego typu (powiedzmy liczbą całkowitą), musiałbyś być bardziej precyzyjny:
Jeśli wiesz na pewno, że Twój zbiór wyników zawsze będzie zawierał co najmniej jeden wiersz (np. SELECT COUNT (*) ...), możesz pominąć sprawdzanie wartości null.
W Twoim przypadku komunikat o błędzie „Nie można rzutować obiektu typu„ System.DBNull ”na typ„ System.String ”oznacza, że pierwsza kolumna zestawu wyników jest wartością DBNUll. To jest od rzutu do łańcucha w pierwszej linii:
Komentarz Marc_s, że nie musisz sprawdzać DBNull.Value, jest błędny.
źródło
Można użyć operatora łączenia wartości null w języku C #
źródło
Istnieje inny sposób obejścia tego problemu. Co powiesz na zmodyfikowanie procedury sklepu? używając funkcji ISNULL (twoje pole, "") sql, możesz zwrócić pusty ciąg, jeśli wartość zwracana jest równa null.
Następnie masz czysty kod jako oryginalną wersję.
źródło
Oto ogólna metoda, której używam do konwersji dowolnego obiektu, który może być DBNull.Value:
stosowanie:
krótszy:
źródło
Przypuszczam, że możesz to zrobić w ten sposób:
Jeśli accountNumber ma wartość null, oznacza to, że był to DBNull, a nie łańcuch :)
źródło
return (accountNumber as string) ?? string.Empty;
, gdy accountNumber nadal będzieobject
. Jeśli wolisz, aby Twoja baza danych znajdowała się na osobnej linii.String.Concat przekształca wartości DBNull i null na pusty ciąg.
Myślę jednak, że tracisz coś na zrozumiałości kodu
źródło
return "" + accountNumber;
?Odkąd mam instancję, która nie jest null i jeśli porównuję z DBNULL, otrzymałem
Operator '==' cannot be applied to operands of type 'string' and 'system.dbnull'
wyjątek, a gdybym spróbował zmienić, aby porównać do NULL, po prostu nie działało (ponieważ DBNull jest obiektem), nawet to jest akceptowana odpowiedź.Postanowiłem po prostu użyć słowa kluczowego „is”. Wynik jest więc bardzo czytelny:
data = (item is DBNull) ? String.Empty : item
źródło
Używam rozszerzenia, aby wyeliminować ten problem za mnie, który może, ale nie musi, być tym, czego szukasz.
To wygląda tak:
Uwaga:
To rozszerzenie nie zwraca
null
wartości! Jeśli elementem jestnull
lub DBNull.Value , zwróci pusty ciąg.Stosowanie:
źródło
Konwertuj jak
źródło