Przypisz null do SqlParameter


189

Poniższy kod podaje błąd - „Brak niejawnej konwersji z DBnull na int.”

SqlParameter[] parameters = new SqlParameter[1];    
SqlParameter planIndexParameter = new SqlParameter("@AgeIndex", SqlDbType.Int);
planIndexParameter.Value = (AgeItem.AgeIndex== null) ? DBNull.Value : AgeItem.AgeIndex;
parameters[0] = planIndexParameter;

4
Musisz rzucić AgeItem.AgeIndex, aby obiekt, jak sądzę ... stackoverflow.com/questions/202271/ ... (btw, dlaczego jest ==na końcu 3 linii?)
Greg

Odpowiedzi:


341

Problem polega na tym, że ?:operator nie może określić typu zwracanego, ponieważ intzwracana jest wartość lub wartość typu DBNull, które nie są kompatybilne.

Oczywiście można rzutować instancję AgeIndex na typ, objectktóry spełnia ?:wymagania.

Możesz użyć ??operatora zerowania koalescencji w następujący sposób

SqlParameter[] parameters = new SqlParameter[1];     
SqlParameter planIndexParameter = new SqlParameter("@AgeIndex", SqlDbType.Int);
planIndexParameter.Value = (object)AgeItem.AgeIndex ?? DBNull.Value;
parameters[0] = planIndexParameter; 

Oto cytat z dokumentacji MSDN dla ?:operatora, który wyjaśnia problem

Albo typ first_expression i second_expression musi być taki sam, lub musi istnieć niejawna konwersja z jednego typu na drugi.


Dlaczego nie rzuca się wyjątku, gdy próbujesz ustawić wartość NULL na obiekt? Myślę, że tak powinno byćAgeItem.AgeIndex as object
Niels Brinch

@Niels Brinch, nie byłoby wyjątku, ponieważ null jest obiektem i dopóki nie spróbujesz go wyłuskać, jest to całkowicie legalne. Jednak w tym przykładzie rzutowanie na obiekt nie jest zerowe, jest to DBNull.Value, który jest typem wartości. ?? operator mówi „jeśli AgetItem.AgeIndex ma wartość NULL, to zwraca DBNull.Value, w przeciwnym razie returen AgeItem.AgeIndex”, wówczas odpowiedź jest rzutowana na obiekt. Aby uzyskać więcej informacji, patrz operator zerowania koalescencji. msdn.microsoft.com/en-us/library/ms173224.aspx
Chris Taylor

3
Technicznie rozwiązanie za pomocą operatora zlewających null ??jest takie samo rozwiązanie jak gdybyś użyć regularną trójskładnikowej ?:- trzeba jeszcze obsady AgeItem.AgeIndexdo obiektu: planIndexParameter.Value = AgeItem.AgeIndex.HasValue ? (object)AgeItem.AgeIndex : DBNull.Value;.
newfurniturey

Jeśli użyjesz zwykłej trójki ?:do porównania specyficznego dla typu, rzutowanie całego wyrażenia nie zadziała. Musisz rzucać parametr nie DBNull tak:someID == 0 ? DBNull.Value : (object)someID
ingredient_15939

To prawda, ale jeśli potrzebujesz użyć wartości zerowej jako parametru wejściowego funkcji, która w wyniku zużywa SqlParameter, a jeśli jest pusta, masz błąd, że w ten sposób nie działa i powinieneś użyć prostej metody If-Else. na przykład: sample.Text.Trim ()! = ""? func (sample.Text): DBNull.Value; nie będzie działać jako?: i ??
QMaster
Korzystając z naszej strony potwierdzasz, że przeczytałeś(-aś) i rozumiesz nasze zasady używania plików cookie i zasady ochrony prywatności.
Licensed under cc by-sa 3.0 with attribution required.