AddWithValue参数为NULL时的异常

时间:2012-11-19 09:40:29

标签: c# .net ado.net

我有以下代码用于指定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中的logSearch.LogID值中获取NULL(但能够接受DBNull)?

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

  3. 参考

    1. Assign null to a SqlParameter
    2. Datatype returned varies based on data in table
    3. Conversion error from database smallint into C# nullable int
    4. What is the point of DBNull?
    5. CODE

          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;
          }
      

4 个答案:

答案 0 :(得分:119)

烦人,不是吗。

您可以使用:

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

或者,也可以使用像“小巧玲珑”这样的工具,这样可以解决所有麻烦。

例如:

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

诱惑为dapper添加一个方法来获取IDataReader ...还不确定这是不是一个好主意。

答案 1 :(得分:41)

我发现只为处理空值的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);

答案 2 :(得分:2)

以防您在调用存储过程时执行此操作:如果您在参数上声明默认值并仅在必要时添加它,我认为它更容易阅读。

例如: (SQL)

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

(C#)

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

我知道这已经过时了,但我觉得这很有帮助,想分享。

答案 3 :(得分:1)

一些问题,必须设置SQLDbType

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

你在哪里输入SqlDbType.NVarChar。必须设置SQL类型。 Enjou