3

我有一个 Oracle 数据表获取为空的列。所以我想保持代码简洁明了,我会使用 ?? 操作数。AlternatePhoneNumber 是我的 C# 模型中的字符串。

AlternatePhoneNumber = customer.AlternatePhoneNumber ?? ""

但是,即使使用该代码,我仍然会收到错误消息。

System.InvalidCastException: Unable to cast object of type 'System.DBNull' to type 'System.String'.

我知道错误是什么意思,但为什么?不能在 DBNull 上使用?null 和 DBNull 本质上不是一样的吗?

谢谢你。

4

7 回答 7

15

??运算符仅适用于实际nulls。

null并且DBNull.Value不一样;DBNull.Value只是一个占位符对象。

此外,在您的操作员执行之前,该异常来自AlternatePhoneNumber属性内部。??(您的代码没有演员表)。

如果customer是类型化数据集中的一行,请NullValue在设计器中更改列的属性。

于 2010-07-09T13:43:15.517 回答
3

null 和 DBNull 是不一样的。System.DBNull 是一个实际的对象。

于 2010-07-09T13:43:45.280 回答
3

问题是那AlternatePhoneNumber是一个字符串。DBNull 不是。

试试这个:

AlternatePhoneNumber = (customer.AlternatePhoneNumber as string) ?? ""
于 2010-07-09T13:45:39.850 回答
2

DBNull 是具有单个值的类型,与空字符串引用不同,这就是您不能使用??. 但是,您可以这样做:

string alternativePhoneNumber = DBNull.Value.Equals(customer) ? string.Empty : ((Customer)customer).AlternatePhoneNumber;
于 2010-07-09T13:46:01.467 回答
2

做这个:

public T IfNull<T>(object o, T value)
{
   return (o == DbNull.Value) ? value : (T)o;       
}
于 2010-07-09T13:49:22.083 回答
1

正如其他答复所述,null表示不引用任何对象的引用,而DBNull它是 ADO.NET 提供的一个类,用于指示数据库(或 DataTable)中的字段或值何时为 NULL。

虽然您可以使用条件(三元)运算符 (?:)来做您想做的事情:

AlternatePhoneNumber = customer.AlternatePhoneNumber is DBNull 
                           ? "" 
                           : customer.AlternatePhoneNumber;

我倾向于将其包装在扩展方法中:

static class NullExtensions
{
    public static T WhenNull<T>( this object value, T whenNullValue )
    {
        return (value == null || value is DBNull)
            ? whenNullValue
            : (T)value;
    }
}

我发现这使代码更易于阅读和理解。

AlternatePhoneNumber = customer.AlternatePhoneNumber.WhenNull( "" );
于 2010-07-09T13:50:57.107 回答
1

DBNull 不是真正的“空”。

这 ”??” - 操作员只检测空引用,而不是模拟“空”行为的对象。

于 2010-07-09T14:05:56.957 回答