【问题标题】:C# ADO.NET: nulls and DbNull -- is there more efficient syntax?C# ADO.NET:null 和 DbNull——有更高效的语法吗?
【发布时间】:2008-10-20 15:23:55
【问题描述】:

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

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

然后我想将DateTime? 的值放入dataPrm.Value,同时考虑nulls。

一开始我以为我会很聪明:

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;

【问题讨论】:

标签: c# ado.net null nullable dbnull


【解决方案1】:

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

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

【讨论】:

  • 我不会说它更“高效”也许“简洁是一个更好的词?
  • 对——你知道我的意思。 :-)
  • 这真是太棒了!我一直在寻找这个。谢谢
  • “高效”在这里也很有意义,如果该解决方案可以更快地帮助 OP 代码。
  • 我就是在找这个!
【解决方案2】:

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

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

你可以这样写:

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

【讨论】:

  • +1 @Gian Marco Gherardi 的回答非常理想。你仍然可以使用三元运算符,只需使用 System.Data.SqlTypes 提供的帮助类
【解决方案3】:

如果你使用它会起作用

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

【讨论】:

  • 是的,那个工作正常,比@Dan 的解决方案短 8 个字符。 :-) 我希望有办法得到 ??解决方案,因为它的语法要短得多。
  • 更新:我找到了一个使用 ?? 的更有效的解决方案。
【解决方案4】:

如果您使用的是 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 );
    }
}

【讨论】:

    【解决方案5】:

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

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

    【讨论】:

      【解决方案6】:

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

      【讨论】:

        猜你喜欢
        • 1970-01-01
        • 2018-03-18
        • 1970-01-01
        • 1970-01-01
        • 1970-01-01
        • 1970-01-01
        • 1970-01-01
        • 1970-01-01
        • 1970-01-01
        相关资源
        最近更新 更多