C # ?? вопрос о нулевом операторе слияния

Я определил свойство Birthday класса Person как DateTime, допускающее значение NULL?, так почему же в следующем примере не должен работать оператор объединения NULL?

cmd.Parameters.Add(new SqlParameter("@Birthday",
   SqlDbType.SmallDateTime)).Value =       
     person.Birthday ?? DBNull.Value; 

Ошибка компилятора, которую я получил, была "Оператор" ?? " не может применяться к операндам типа 'System.DateTime?' и 'System.DBNull' "

Следующее также получило ошибку компиляции:

cmd.Parameters.Add(new SqlParameter("@Birthday", 
  SqlDbType.SmallDateTime)).Value = 
   (person.Birthday == null) ? person.Birthday:DBNull.Value;

Я добавил приведение к (объекту) в соответствии с рекомендациями Refactor, и он скомпилировался, но не работал должным образом, и в обоих случаях значение было сохранено в базе данных sqlserver как null.

SqlDbType.SmallDateTime)).Value =       
         person.Birthday ?? (object)DBNull.Value;

Может кто-нибудь объяснить, что здесь происходит?

Мне нужно было использовать следующий неуклюжий код:

   if (person.Birthday == null) 
    cmd.Parameters.Add("@Birthday", SqlDbType.SmallDateTime).Value 
      = DBNull.Value;
     else cmd.Parameters.Add("@Birthday", SqlDbType.SmallDateTime).Value = 
          person.Birthday;

person Lill Lansey    schedule 06.08.2010    source источник
comment
Дубликат stackoverflow.com/questions/218808/   -  person sgriffinusa    schedule 06.08.2010
comment
Получил это из другого сообщения: SqlDbType.SmallDateTime)). Value = person.Birthday ?? (объект) DBNull.Value; Спасибо!   -  person Lill Lansey    schedule 06.08.2010


Ответы (3)


Проблема в том, что DateTime? и DBNull.Value не одного типа, поэтому вы не можете использовать для них нулевой оператор объединения.

В вашем случае вы можете сделать person.Birthday ?? (object)DBNull.Value, чтобы передать значение типа object через Add()

person Dave D    schedule 06.08.2010

Я предпочитаю перебирать мои параметры непосредственно перед выполнением запроса, при необходимости меняя все экземпляры null на DBNull, например:

foreach (IDataParameter param in cmd.Parameters)
    if (param.Value == null)
        param.Value = DBNull.Value;

Это позволяет мне оставить нулевые значения как есть, а потом просто поменять их массово.

person JYelton    schedule 06.08.2010
comment
Моя проблема с этим - дополнительные накладные расходы на повторение параметров после факта, а не на немедленную их обработку. - person Andrew; 24.03.2017

Ваша первая проблема заключается в том, что для оператора ?? или ?: объекты для любого выбора должны быть одного типа. Вот они другого типа.

person James Curran    schedule 06.08.2010
comment
Итак, что делает ?:? edit: Nevermind, я знал это, просто никогда раньше не видел, чтобы эти 2 символа так сложились. msdn.microsoft.com/en-us/library/ty67wk28.aspx - person Allen Rice; 06.08.2010