AddWithValue参数为NULL时exception

我有以下代码为SQL查询指定参数。 当我使用Code 1时,我得到以下例外; 但是当我使用Code 2时工作正常。 在Code 2我们检查了null,因此if..else块。

例外:

参数化查询'(@application_ex_id nvarchar(4000))SELECT E.application_ex_id A'需要参数“@application_ex_id”,该参数未提供。

代码1

 command.Parameters.AddWithValue("@application_ex_id", logSearch.LogID); 

代码2

 if (logSearch.LogID != null) { command.Parameters.AddWithValue("@application_ex_id", logSearch.LogID); } else { command.Parameters.AddWithValue("@application_ex_id", DBNull.Value ); } 

  1. 你能解释为什么它不能从代码1(但能够接受DBNull)logSearch.LogID值NULL?

  2. 有更好的代码来处理这个?

参考

  1. 将null分配给SqlParameter
  2. 返回的数据types取决于表中的数据
  3. 从数据库smallint转换为C#可空int的转换错误
  4. DBNull有什么意义?

  public Collection<Log> GetLogs(LogSearch logSearch) { Collection<Log> logs = new Collection<Log>(); using (SqlConnection connection = new SqlConnection(connectionString)) { connection.Open(); string commandText = @"SELECT * FROM Application_Ex E WHERE (E.application_ex_id = @application_ex_id OR @application_ex_id IS NULL)"; using (SqlCommand command = new SqlCommand(commandText, connection)) { command.CommandType = System.Data.CommandType.Text; //Parameter value setting //command.Parameters.AddWithValue("@application_ex_id", logSearch.LogID); if (logSearch.LogID != null) { command.Parameters.AddWithValue("@application_ex_id", logSearch.LogID); } else { command.Parameters.AddWithValue("@application_ex_id", DBNull.Value ); } using (SqlDataReader reader = command.ExecuteReader()) { if (reader.HasRows) { Collection<Object> entityList = new Collection<Object>(); entityList.Add(new Log()); ArrayList records = EntityDataMappingHelper.SelectRecords(entityList, reader); for (int i = 0; i < records.Count; i++) { Log log = new Log(); Dictionary<string, object> currentRecord = (Dictionary<string, object>)records[i]; EntityDataMappingHelper.FillEntityFromRecord(log, currentRecord); logs.Add(log); } } //reader.Close(); } } } return logs; } 

讨厌,不是吗?

您可以使用:

 command.Parameters.AddWithValue("@application_ex_id", ((object)logSearch.LogID) ?? DBNull.Value); 

或者,也可以使用像“小巧玲珑”这样的工具,它可以为你做所有的事情。

例如:

 var data = conn.Query<SomeType>(commandText, new { application_ex_id = logSearch.LogID }).ToList(); 

试图添加一个方法来精简获取IDataReader …不知道这是否是一个好主意。

我发现只写一个处理空值的SqlParameterCollection的扩展方法更容易:

 public static SqlParameter AddWithNullableValue( this SqlParameterCollection collection, string parameterName, object value) { if(value == null) return collection.AddWithValue(parameterName, DBNull.Value); else return collection.AddWithValue(parameterName, value); } 

那么你就像这样称呼它:

 sqlCommand.Parameters.AddWithNullableValue(key, value); 

以防万一你在调用存储过程的时候这么做:我认为如果你在参数上声明了一个默认值,并且只在需要的时候添加它,那么读取会更容易。

例如:(sql)

 DECLARE PROCEDURE myprocedure @myparameter [int] = NULL AS BEGIN 

(C#)

 int? myvalue = initMyValue(); if (myvalue.hasValue) cmd.Parameters.AddWithValue("myparamater", myvalue); 

我知道这是旧的,但我觉得这有帮助,想分享。

一些问题,允许与必要的设置SQLDbType

 command.Parameters.Add("@Name", SqlDbType.NVarChar); command.Parameters.Value=DBNull.Value 

你在哪里inputSqlDbType.NVarChar。 必须设置的SQLtypes。 Enjou

像这样创build一个静态类:

 public static class Extensions { public static string RemoveNulls(this string container) { if (container == null) container = ""; return container; } } 

然后在你的代码中,这样做:

 Parameters.AddWithValue(sName, Value.RemoveNulls()); 

这是防弹的,非常容易使用