【问题标题】:Is there a more elegant form for assigning NULL to InsertCommand's NVarChar?是否有更优雅的形式将 NULL 分配给 InsertCommand 的 NVarChar?
【发布时间】:2012-10-19 19:19:13
【问题描述】:

这段代码非常适合我:

if (someStr == null)
  da.InsertCommand.Parameters.Add("@SOMESTR", SqlDbType.NVarChar).Value = DBNull.Value;
else
  da.InsertCommand.Parameters.Add("@SOMESTR", SqlDbType.NVarChar).Value = someStr;

但我的直觉告诉我,它可能有一个单行版本。比如:

  da.InsertCommand.Parameters.Add("@SOMESTR", SqlDbType.NVarChar).Value = someStr==null ? DBNull.Value : someStr ;

但是我刚刚在上面发布的单行代码当然失败了,因为DBNull.Value 没有转换为字符串。

有没有办法完成我如此渴望的一个班轮?

【问题讨论】:

标签: c# sql-server sql-insert sqldataadapter


【解决方案1】:

您可以将 someStr 强制转换为对象

例如:

da.InsertCommand.Parameters.Add("@SOMESTR", SqlDbType.NVarChar).Value = someStr==null ? DBNull.Value : (object)someStr;

或者您可以按照 Oded 和 Servy 的建议进行操作并使用扩展方法。虽然它可能会添加几行代码,但可以避免重复代码。

正如 Servy 指出的那样,将其放在 object 上可能会导致混乱。出于这个原因,我会把它放在SqlParameter

public static void SetValue(this SqlParameter parameter, object value)
{
    parameter.Value = value == null ? DBNull.Value : value;
}

那就这样用吧

da.InsertCommand.Parameters.Add("@SOMESTR", SqlDbType.NVarChar).SetValue(someStr);

【讨论】:

    【解决方案2】:

    创建一个函数或扩展方法来执行测试并根据需要进行分配。传入someStr 和参数名称。

    然后您将能够在一行中设置参数。

    【讨论】:

    • 这很优雅,但违背了减少代码行数的目的。
    • @scatmoi - 为什么这个目标如此理想?如果你适当地分解出这样一个函数,它可以被许多参数重用,从而降低整体 LOC。
    • @scatmoi - 嗯,MS 包含它的第一个反对意见是它很容易自己实现。他们无法预见某人可能拥有的每一个可能的需求——你能想象如果他们停止框架库的大小会是多少某处
    【解决方案3】:

    您可以使用以下扩展方法(如果您愿意,也可以将其设为非扩展方法)

    public static object ConvertNull(this object obj)
    {
        return obj ?? DBNull.Value;
    }
    

    你可以这样做:

    da.InsertCommand.Parameters.Add("@SOMESTR", SqlDbType.NVarChar).Value = someStr.ConvertNull()
    

    【讨论】:

    • 太漂亮了。但是将额外的代码行从一个地方移动到另一个地方。我希望 ConvertNull() 是一个 C# 库函数。
    • @scatmoi 如果您只执行一次,它会增加代码行数。如果你不止一次这样做,它会减少它。如果您碰巧只这样做过一次,那么就不要使用该方法(但我怀疑是这种情况)。
    • 请注意,您需要在一个扩展类中使用它,该类只包含在您经常处理 DB 命令的上下文中;通过将其放在通用扩展中为object 的智能感知添加额外的“混乱”可能弊大于利..
    • @Servy 等人你当然是对的,但它提出了一个问题:微软为什么没有在其任何 VS 版本中提供这个作为库方法?
    • @scatmoi 好吧,对于初学者来说,你可以很容易地让你没有理由需要他们为你做。接下来,与任何其他功能一样,它不存在,因为它不是:1) 考虑 2) 选择用于开发 2) 编码 3) 测试 4) 部署。我的猜测是这个在#1 之前停止了,如果没有,那就是#2。语言特性不“默认存在,除非有理由排除它们”。默认情况下,在完成实现它们所需的所有步骤之前,不会实现功能。
    【解决方案4】:
    da.InsertCommand.Parameters.Add("@SOMESTR", SqlDbType.NVarChar).Value = ((object)someStr) ?? DBNull.Value; 
    

    【讨论】:

      【解决方案5】:

      编写一个用于插入的存储过程,将参数的默认值设置为 null,将该存储过程用于插入命令,然后不要只将该参数传递给该 sproc..

      【讨论】:

        猜你喜欢
        • 1970-01-01
        • 2020-02-12
        • 2013-01-05
        • 1970-01-01
        • 1970-01-01
        • 1970-01-01
        • 2017-01-16
        • 2018-05-31
        • 2012-12-16
        相关资源
        最近更新 更多