什么在DBNull

我有一个存储过程,其参数可以为十进制列。 我写的方法需要一个Dictionary来传递参数名称和值。

但是,当我这样做时,我将reflection用于GetValue

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

实质上,所有DBNull.Value返回都是String.Empty 。 那么如何确保将null正确传递给SQL Server? 否则会抛出exception,因为列数据类型无效。 文档说明,使用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

如果你有Dictionary ,你在字典中有一个值,这样:

 var dictionary = new Dictionary() { { "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()); 

不应该以这种方式将它传递给过程,因为你说它被声明为可以为空的十进制字段。

我想你必须从Dictionary中获取每个值,然后在将参数传递给命令之前使用如下所示的代码。 换句话说,将null存储为Dictionary中的值,而不是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));