What in the DBNull

本文关键字:DBNull the in What | 更新日期: 2023-09-27 18:30:23

>我有一个存储过程,它有一个参数,该参数可对十进制列为空。我编写的方法需要Dictionary<string, string>传递参数名称和值。

但是,当我使用反射来GetValue时,当我这样做时:

collection.Add(model.Name, DBNull.Value.ToString());

从本质上讲,所有DBNull.Value回报都将是String.Empty。那么,如何确保将 null 正确传递给 SQL Server呢?否则将引发异常,因为列数据类型无效。文档指出,ToString它将返回String.Empty .

DBNull 是一个单例类,这意味着只有这个实例 类可以存在。如果数据库字段缺少数据,则可以使用 DBNull.Value 属性,用于显式将 DBNull 对象值分配给 该领域。但是,大多数数据提供程序会自动执行此操作。自 评估数据库字段以确定其值是否为 DBNull, 可以将字段值传递给 DBNull.Value.Equals 方法。 但是,这种方法很少使用,因为有许多 评估数据库字段是否存在缺失数据的其他方法。这些 包括 Visual Basic IsDBNull 函数、Convert.IsDBNull 方法, DataTableReader.IsDBNull 方法, IDataRecord.IsDBNull 方法和其他几种方法。

这将按以下方式添加到数据库中:

command.Parameters.AddWithValue(parameter.Key, parameter.Value);

传统的 Ado.Net SqlDataReader

What in the DBNull

我认为您必须从字典中获取每个值,然后在将参数传递给命令之前使用如下所示的代码。换句话说,将 null 存储为字典中的值,而不是 DBNull,然后调用下面的代码从 null 转换为 DBNull.Value。

        SqlParameter firstNameParam = new SqlParameter("FirstName", System.Data.SqlDbType.NVarChar);
        string firstNameValue = null; // this is the value from the Dictionary
        if (firstNameValue == null) {
            firstNameParam.Value = DBNull.Value;
        }
        else {
            firstNameParam.Value = firstNameValue;
        }

重构后,您可以执行以下操作:

  public static object ToDBNull(object value) {
        if (value == null) {
            return DBNull.Value;
        }
        else {
            return value;
        }
    }

然后像这样调用 ToDBNull 函数:

        cmd.Parameters.AddWithValue("FirstName", ToDBNull(firstNameValue));

如果您有 Dictionary<string, string> ,并且字典中有一个值,例如:

var dictionary = new Dictionary<string, string>() { { "hello", null } };
string data = dictionary["hello"];
var dec = data == null ? (decimal?)null : Convert.ToDecimal(data);

您可以编写一个小的扩展方法,以便更轻松地将其传递给命令

public static object ValueOrDbNull(this decimal? value)
{
    if (value.HasValue)
    {
        return value;
    }
    return DBNull.Value;
}

然后将其添加到您的命令中,如下所示:

command.Parameters.Add("@your_proc_param", dec.ValueOrDbNull());

以这种方式将其传递给过程应该没有任何问题,因为您说它被声明为可为空的十进制字段。