C#ADO.NET:nulls和DbNull——有更有效的语法吗?

C#ADO.NET:nulls和DbNull——有更有效的语法吗?,c#,ado.net,null,nullable,dbnull,C#,Ado.net,Null,Nullable,Dbnull,我有一个DateTime?,我正试图使用DbParameter将其插入一个字段中。我这样创建参数: DbParameter datePrm = updateStmt.CreateParameter(); datePrm.ParameterName = "@change_date"; 然后我想把DateTime?的值放入dataPrm.value中,同时考虑nulls 起初我以为我会很聪明: datePrm.Value = nullableDate ?? DBNull.Value; 但这失败了

我有一个
DateTime?
,我正试图使用
DbParameter
将其插入一个字段中。我这样创建参数:

DbParameter datePrm = updateStmt.CreateParameter();
datePrm.ParameterName = "@change_date";
然后我想把
DateTime?
的值放入
dataPrm.value
中,同时考虑
null
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说:

这个??运算符返回左操作数(如果不为null),否则返回右操作数

这正是我想要的

更新2:好吧,最后有点明显:

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

如果你使用

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

我认为您第二次尝试时出现的错误是由于nullableDate.Value和DBNull.Value是不同的类型,三元运算符在这两种情况下都需要选择一种类型来返回。我没有环境来测试这一点,但我认为这应该适合您:

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

我这样做的方式是,我有一个静态实用程序类,它只是检查参数值是否为null,然后我将该值设置为do DBNull。我只是在调用Execute之前这样做。

如果您使用的是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 );
    }
}
公共静态类DBNullableExtensions
{
公共静态对象ToDBValue(此可空值),其中T:struct
{ 
return value.HasValue?(object)value.value:DBNull.value;
}
}
班级计划
{
静态void Main(字符串[]参数)
{
int?x=null;
Console.WriteLine(x.ToDBValue()==DBNull.Value);
}
}

啊哈!我找到了一个比@Trebz更有效的解决方案

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

如果您使用的是SQLServer,则
System.Data.SqlTypes
命名空间包含一些实用程序类,可以避免烦人的类型转换。例如,与此相反:

var val = (object) "abc" ?? DBNull.Value;
你可以这样写:

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

是的,这个很好用,比@Dan的解决方案短8个字符。:-)我希望有一种方法可以得到这个??解决方案很有效,因为它的语法要短得多。更新:我发现了一个更有效的解决方案,使用???。我不会说它更“有效”也许“简明是一个更好的词?对——你知道我的意思。:-)这真是太好了!我一直在寻找这个。谢谢“有效”“如果解决方案有助于加快运算代码的速度,那么在这里也有意义。我正是在寻找这个+1@Gian Marco Gherardi的答案是理想的。您仍然可以使用三元运算符,只需使用System.Data.SqlTypes提供的助手类即可