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

我有一个DateTime? 我试图插入到使用DbParameter字段。 我正在创build这样的参数:

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

然后我想把DateTime?的值DateTime? 进入dataPrm.Value同时占null

我以为我会很聪明:

 datePrm.Value = nullableDate ?? DBNull.Value; 

但失败的错误

运营商“??” 不能应用于“System.DateTime?”types的操作数 和“System.DBNull”

所以我猜想,只有第二个参数是第一个参数的非空值版本才有效。 那么我去了:

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

但是这也不起作用:

条件expression式的types不能确定,因为没有“System.DateTime”和“System.DBNull”之间的隐式转换

但我不想在这些types之间转换!

到目前为止,我唯一可以工作的是:

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

那真的是我写这个的唯一方法吗? 有没有办法使用三元运算符来实现单线程工作?

更新:我真的不明白为什么? 版本不起作用。 MSDN说:

?? 如果操作数不为null,则返回左操作数,否则返回右操作数。

这正是我想要的!

Update2:最后这是很明显的:

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

啊哈! 我发现比@ Trebz更有效的解决scheme!

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

如果您使用的是C#3.0,则可以创build一个扩展方法来执行此操作:

 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 ); } } 

它会工作,如果你使用

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

如果您正在使用SQLServer, System.Data.SqlTypes命名空间包含一些实用程序类,避免恼人的types转换。 例如,而不是这个:

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

你可以写这个:

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

我认为你的第二次尝试的错误是由于nullableDate.Value和DBNull.Value是不同的types和三元运算符需要select一种types返回在这两种情况下。 我没有环境来testing,但我认为这应该为你工作:

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

我这样做的方式,是我有一个静态实用程序类,只是通过检查,看看是否参数值为空,然后我设置的值做DBNull。 在我致电Execute之前,我只是这么做的。