是否可以在C#中合并字符串和DBNull?

Bes*_*ska 10 c# null-coalescing-operator

我正在编写一个C#例程来调用存储过程.在我传入的参数列表中,其中一个值可能合法地为空.所以我以为我会使用这样的一行:

cmd.Parameters.Add(new SqlParameter("@theParam", theParam ?? DBNull.Value));
Run Code Online (Sandbox Code Playgroud)

不幸的是,这会返回以下错误:

CS0019:运营商'??' 不能应用于'string'和'System.DBNull'类型的操作数

现在,这似乎已经足够清楚,但我不明白其背后的基本原理.为什么这不起作用?(通常情况下,当我不明白为什么某些东西不能正常工作时,并不是它无法正常工作......而是我做错了.)

我是否真的需要将其延伸到更长的if-then声明中?

编辑:(顺便说一句,对那些建议只使用"null"的人,它不起作用.我原来认为null也会自动翻译成DBNull,但它显然没有.(谁知道?))

Joe*_*orn 16

不是那样的,没有.类型必须匹配.三元组也是如此.

现在,通过"匹配",我并不是说他们必须是一样的.但它们必须兼容分配.基本上:在同一个继承树中.

解决此问题的一种方法是将字符串转换为对象:

var result = (object)stringVar ?? DBNull.Value;
Run Code Online (Sandbox Code Playgroud)

但我不喜欢这个,因为这意味着你更依赖于SqlParameter构造函数来使你的类型正确.相反,我喜欢这样做:

cmd.Parameters.Add("@theParam", SqlDbTypes.VarChar, 50).Value = theParam;
// ... assign other parameters as well, don't worry about nulls yet

// all parameters assigned: check for any nulls
foreach (var p in cmd.Parameters) 
{ 
    if (p.Value == null) p.Value = DBNull.Value; 
}
Run Code Online (Sandbox Code Playgroud)

另请注意,我明确声明了参数类型.

  • 我的意思是`foreach`中的位可能是SqlCommand的扩展方法. (2认同)

kwc*_*cto 5

new SqlParameter("@theParam", (object)theParam ?? DBNull.Value)
Run Code Online (Sandbox Code Playgroud)