C# SqlCommand.Parameters.AddWithValue问题:过程或函数X需要参数@Y,但未提供该参数

C# SqlCommand.Parameters.AddWithValue问题:过程或函数X需要参数@Y,但未提供该参数,c#,parameters,sqlcommand,C#,Parameters,Sqlcommand,我对下面的代码有问题。我正在将参数(List)传递给执行以下代码的方法 SQL Server在执行时抛出一个错误,表示proc需要一个未提供的参数。我知道并理解这一错误,在逐步执行代码时,我可以看到cmdExecuteReader对象包含一组具有正确名称和值的参数。有什么问题吗 public SqlDataReader ExecuteReader(string storedProcedure, List<SqlParameter> parameters = null)

我对下面的代码有问题。我正在将参数(
List
)传递给执行以下代码的方法

SQL Server在执行时抛出一个错误,表示proc需要一个未提供的参数。我知道并理解这一错误,在逐步执行代码时,我可以看到
cmdExecuteReader
对象包含一组具有正确名称和值的参数。有什么问题吗

     public SqlDataReader ExecuteReader(string storedProcedure, List<SqlParameter> parameters = null)
        {
                    SqlCommand cmdExecuteReader = new SqlCommand()
                    {
                        CommandType = System.Data.CommandType.Text,
                        Connection = conn,
                        CommandText = storedProcedure
                    };

                    if (parameters != null)
                    {
                        foreach (SqlParameter param in parameters)
                        {
                            cmdExecuteReader.Parameters.AddWithValue(param.ParameterName, param.Value);
                        }
                    }

                    if (conn.State == System.Data.ConnectionState.Closed)
                        conn.Open();
                    return cmdExecuteReader.ExecuteReader();
       }
公共SqlDataReader ExecuteReader(字符串存储过程,列表参数=null) { SqlCommand cmdExecuteReader=新SqlCommand() { CommandType=System.Data.CommandType.Text, 连接=连接, CommandText=StoredProcess }; if(参数!=null) { foreach(参数中的SqlParameter参数) { cmdExecuteReader.Parameters.AddWithValue(param.ParameterName,param.Value); } } if(conn.State==System.Data.ConnectionState.Closed) conn.Open(); 返回cmdExecuteReader.ExecuteReader(); }
是否将任何参数的
.Value
设置为
null
?如果是这样,它们就不会被发送。尝试:

cmdExecuteReader.Parameters.AddWithValue(param.ParameterName,
        param.Value ?? DBNull.Value);
(注意null与
DBNull.Value
合并)

另外,请注意,
AddWithValue
可能会影响查询计划的重用,因为(对于字符串等)它使用值的长度。如果需要最大性能,最好使用定义的大小手动设置参数

还请注意,传入列表中的一些参数可能是输入-输出、输出或结果。我很想用以下东西来代替:

SqlParameter newParam = cmdExecuteReader.Parameters.Add(
      param.ParameterName, param.SqlDbType, param.Size);
newParam.Value = param.Value ?? DBNull.Value;
newParam.Direction = param.Direction;

我做了你想做的事情,这里有一些例子:

public int ChangeState(int id, int stateId)
{
    return DbUtil.ExecuteNonQuerySp("changeDossierState", Cs, new { id, stateId });
}

public IEnumerable<Dossier> GetBy(int measuresetId, int measureId, DateTime month)
{
    return DbUtil.ExecuteReaderSp<Dossier>("getDossiers", Cs, new { measuresetId, measureId, month });
}
public int-ChangeState(int-id,int-stateId)
{
返回DbUtil.ExecuteNonQuerySp(“ChangeDossiersState”,Cs,new{id,stateId});
}
公共IEnumerable GetBy(int-measurestid、int-measureId、DateTime-month)
{
返回DbUtil.ExecuteReaderSp(“getDossiers”,Cs,new{measuresetId,measureId,month});
}
我建议你去看看

下载示例解决方案(其中包含DAL示例项目)

+1。我个人不使用AddWithValue,更喜欢显式定义数据类型(和大小)-否则,您可能最终会做出错误的假设(例如.NET字符串值作为NVARCHAR传入),这让我很怀疑