[c#] C # ADO.NET: nulls и DbNull - есть ли более эффективный синтаксис?



2 Answers

Если вы используете C # 3.0, вы можете создать метод расширения для этого:

public static class DBNullableExtensions
{
    public static object ToDBValue<T>(this Nullable<T> value) where T:struct
    { 
        return value.HasValue ? (object)value.Value : DBNull.Value;
    }
}


class Program
{
    static void Main(string[] args)
    {
        int? x = null;

        Console.WriteLine(  x.ToDBValue() == DBNull.Value );
    }
}
Question

У меня есть DateTime? что я пытаюсь вставить в поле с помощью DbParameter . Я создаю параметр следующим образом:

DbParameter datePrm = updateStmt.CreateParameter();
datePrm.ParameterName = "@change_date";

А потом я хочу поставить значение DateTime? в dataPrm.Value при учете null dataPrm.Value s.

Сначала я думал, что буду умным:

datePrm.Value = nullableDate ?? DBNull.Value;

но это не удается с ошибкой

Оператор '??' не могут применяться к операндам типа «System.DateTime»? и 'System.DBNull'

Поэтому я предполагаю, что это работает только в том случае, если второй аргумент является непустой версией первого аргумента. Тогда я пошел:

datePrm.Value = nullableDate.HasValue ? nullableDate.Value : DBNull.Value;

но это тоже не работает:

Тип условного выражения не может быть определен, потому что нет никакого неявного преобразования между «System.DateTime» и «System.DBNull»,

Но я не хочу конвертировать между этими типами!

Единственное, что я могу сделать, это:

if (nullableDate.HasValue)
  datePrm.Value = nullableDate.Value;
else
  datePrm.Value = DBNull.Value;

Неужели это единственный способ написать это? Есть ли способ получить однострочный трафик с использованием тернарного оператора?

Обновление: я действительно не понимаю, почему ??? версия не работает. MSDN говорит:

The ?? оператор возвращает левый операнд, если он не является нулевым, иначе он возвращает правый операнд.

Это именно то, что я хочу!

Update2: Ну, в конце концов, это было очевидно:

datePrm.Value = nullableDate ?? (object)DBNull.Value;



Если вы используете SQLServer, System.Data.SqlTypes имен System.Data.SqlTypes содержит некоторые классы утилиты, которые избегают раздражающего типа. Например, вместо этого:

var val = (object) "abc" ?? DBNull.Value;

вы можете написать это:

var val = "abc" ?? SqlString.Null;



Способ, которым я это делаю, заключается в том, что у меня есть статический класс утилиты, который просто проходит, и проверяет, имеет ли значение параметра значение null, а затем я устанавливаю значение для DBNull. Я просто делаю это, прежде чем позвонить в Execute.




Related