C# ADO.NET:null 和 DbNull — 是否有更有效的语法?

发布于 2024-07-06 19:33:50 字数 1292 浏览 5 评论 0原文

我有一个 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 说:

?? 如果左侧操作数不为空,则运算符返回左侧操作数,否则返回右侧操作数。

这正是我想要的!

更新2:嗯,最后很明显:

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

I've got a DateTime? that I'm trying to insert into a field using a DbParameter. I'm creating the parameter like so:

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

And then I want to put the value of the DateTime? into the dataPrm.Value while accounting for nulls.

I thought initially I'd be clever:

datePrm.Value = nullableDate ?? DBNull.Value;

but that fails with the error

Operator '??' cannot be applied to operands of type 'System.DateTime?' and 'System.DBNull'

So I guess that only works if the second argument is a non-nullable version of the first argument. So then I went for:

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

but that doesn't work either:

Type of conditional expression cannot be determined because there is no implicit conversion between 'System.DateTime' and 'System.DBNull'

But I don't want to convert between those types!

So far the only thing I can get to work is:

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

Is that really the only way I can write this? Is there a way to get a one-liner using the ternary operator to work?

Update: I don't really get why the ?? version doesn't work. MSDN says:

The ?? operator returns the left-hand operand if it is not null, or else it returns the right operand.

That's exactly what I want!

Update2: Well it was kind of obvious in the end:

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

如果你对这篇内容有疑问,欢迎到本站社区发帖提问 参与讨论,获取更多帮助,或者扫码二维码加入 Web 技术交流群。

扫码二维码加入Web技术交流群

发布评论

需要 登录 才能够评论, 你可以免费 注册 一个本站的账号。

评论(6

橘寄 2024-07-13 19:33:50

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

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

Ah ha! I found an even more efficient solution than @Trebz's!

datePrm.Value = nullableDate ?? (object)DBNull.Value;
物价感观 2024-07-13 19:33:50

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

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

您可以这样写:

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

If you are using SQLServer, the System.Data.SqlTypes namespace contains some utility classes that avoid the annoying type casting. For example instead of this:

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

you can write this:

var val = "abc" ?? SqlString.Null;
吻安 2024-07-13 19:33:50

如果你使用的话它会起作用

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

It would work if you used

datePrm.Value = nullableDate.HasValue ? (object)nullableDate.Value : DBNull.Value;
聊慰 2024-07-13 19:33:50

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

If you're using C# 3.0 you can create an extension method to do this easy:

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 );
    }
}
方圜几里 2024-07-13 19:33:50

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

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

I think the error with your second attempt is due to nullableDate.Value and DBNull.Value being different types and the ternary operator needing to pick one type to return in both cases. I don't have the environment to test this but I think this should work for you:

datePrm.Value = nullableDate.HasValue ? (object)nullableDate.Value : (object)DBNull.Value;
无敌元气妹 2024-07-13 19:33:50

我这样做的方式是,我有一个静态实用程序类,它只是遍历并检查参数值是否为 null,然后我设置该值来执行 DBNull。 我只是在调用执行之前执行此操作。

The way that I do it, is I have a static utility class that just goes through and checks to see if the parameter value is null, then i set the value to do DBNull. I just do that before i call the Execute.

~没有更多了~
我们使用 Cookies 和其他技术来定制您的体验包括您的登录状态等。通过阅读我们的 隐私政策 了解更多相关信息。 单击 接受 或继续使用网站,即表示您同意使用 Cookies 和您的相关数据。
原文