2012-09-16 12 views
9

Mam kilka otaczaniem na mojej stronie, która może być pusty, ponieważ są opcjonalne i Mam ten kod DALPrzechodząc DBNull.Value i pustą wartość pola tekstowego do bazy

parameters.Add(new SqlParameter("@FirstName", FirstName)); 
parameters.Add(new SqlParameter("@LastName", LastName)); 
parameters.Add(new SqlParameter("@DisplayName", DisplayName)); 
parameters.Add(new SqlParameter("@BirthDate", BirthDate)); 
parameters.Add(new SqlParameter("@Gender", Gender)); 

Każde z tych pól może być puste. Problem jest wtedy, gdy są one puste otrzymam Procedure XXX requires @FirstName which was not supplied

Potem zmieniłem kod do

parameters.Add(new SqlParameter("@FirstName", String.IsNullOrEmpty(FirstName) ? DBNull.Value : (object)FirstName)); 
parameters.Add(new SqlParameter("@LastName", String.IsNullOrEmpty(LastName) ? DBNull.Value : (object) LastName)); 
parameters.Add(new SqlParameter("@DisplayName", String.IsNullOrEmpty(DisplayName) ? DBNull.Value : (object) DisplayName)); 
parameters.Add(new SqlParameter("@BirthDate", BirthDate.HasValue ? (object)BirthDate.Value : DBNull.Value)); 
parameters.Add(new SqlParameter("@Gender", String.IsNullOrEmpty(Gender) ? DBNull.Value : (object) Gender)); 

Ale to wygląda plączą mi się zwłaszcza odlewania do object ponieważ trójargumentowy stwierdzenie wymaga zarówno wartość być tego samego typu.

Dlaczego w bazie danych nie jest traktowany pusty ciąg znaków lub łańcuch o wartości pustej? NULL Jeśli muszę przekonwertować to na DBNull.Value jest czyściejszy sposób? Zapisanie wartości jako pustego ciągu w bazie danych mogłoby pomóc, ale zapytanie o numer NULL w bazie danych również stanie się kłopotliwe.

Proszę podać porady dotyczące powszechnych praktyk lub czegoś w tym rodzaju.

Odpowiedz

10

Po pierwsze, istnieją 2 bardziej poręczne przeciążenia:

command.Parameters.Add("@name").Value = value; 

lub

command.Parameters.AddWithValue("@name", value); 

Osobiście używam następującą metodę rozszerzenia:

public static object DbNullIfNull(this object obj) 
{ 
    return obj != null ? obj : DBNull.Value; 
} 

command.Parameters.AddWithValue("@name", value.DbNullIfNull()); 

lub

public static object DbNullIfNullOrEmpty(this string str) 
{ 
    return !String.IsNullOrEmpty(str) ? str : (object)DBNull.Value; 
} 
+0

Nie mam dostępu do obiektu polecenia, ponieważ pobrałem go do klasy Base, dzięki czemu mogę go używać z kilkoma bazami danych [unikając zależności od konkretnej bazy danych]. Podoba mi się podejście metod rozszerzenia. Dzięki. – codingbiz

+0

Myślę, że coś jest nie tak z 'DbNullIfNull'. Nie mogłem zrozumieć tamtej logiki, więc wpisałem ją do mojego projektu .NET 4.0 i na pewno jest źle! Zgaduję, że miałeś napisać 'return (obj! = Null)? obj: DBNull.Value; 'zamiast' return obj? = null? obj: DBNull.Value; 'Po prostu FYI. – jp2code

+0

@ jp2code: Oczywiście, to był tylko literówka. Dzięki! Naprawiony. – abatishchev

2

Możliwe jest ustawienie parametrów domyślnych w procedurze przechowywanej, co czyni je opcjonalnymi.

create procedure XXX 
(
    @FirstName nvarchar(50) = null, 
    @LastName nvarchar(50) = null, 
    ... 
) 
+0

to też działa, ale nie uczyni moje DAL przenośne, więc muszę obsługiwać wartości null w moim kodu. Nie wiem, czy ORACLE zezwala na domyślne wartości parametrów. (+1) anyway – codingbiz

5

Niewielkie ponowne przeliczenie może sprawić, że kod będzie mniej brudny. Spróbuj tego

dbParams.Add(SetDBNullIfEmpty("@FirstName", FirstName)); 
dbParams.Add(SetDBNullIfEmpty("@LastName", LastName)); 
dbParams.Add(SetDBNullIfEmpty("@DisplayName", DisplayName)); 
dbParams.Add(SetDBNullIfEmpty("@BirthDate", BirthDate)); 
dbParams.Add(SetDBNullIfEmpty("@Gender", Gender)); 

private SqlParameter SetDBNullIfEmpty(string parmName, string parmValue) 
{ 
    return new SqlParameter(parmName, String.IsNullOrEmpty(parmValue) ? DBNull.Value : (object)parmValue)); 
} 
+0

Dzięki tobie sir – codingbiz

Powiązane problemy