2010-05-06 10 views
7

Tengo un problema con la siguiente pieza de código. Estoy pasando un parámetro (List<SqlParameter>) a un método que ejecuta el siguiente código.SqlCommand.Parameters.AddWithValue issue: Procedimiento o función X espera el parámetro @Y, que no se suministró

Cuando se ejecuta SQL Server arroja un error que dice que el proc espera un parámetro que no se proporcionó. Conozco este error y lo entiendo, y al recorrer el código puedo ver que el objeto cmdExecuteReader tiene una colección de parámetros con el nombre y el valor correctos. ¿Cual podría ser el problema?

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

Respuesta

10

Es el conjunto de .Valuenull para cualquiera de los parámetros? Si es así, no son enviados. Proveedores:

cmdExecuteReader.Parameters.AddWithValue(param.ParameterName, 
     param.Value ?? DBNull.Value); 

(tenga en cuenta el nulo coalescencia con DBNull.Value)

Además, tenga en cuenta que AddWithValue puede afectar a su consulta de plan de reutilización, como (por cuerdas, etc.) que utiliza la longitud de la valor. Si necesita un rendimiento máximo, es mejor configurar el parámetro manualmente con los tamaños definidos.

También tenga en cuenta que potencialmente algunos de los parámetros en la lista entrante podrían ser entrada-salida, salida o resultado. Yo estaría muy tentado a sustituir a algo más parecido a:

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

+1. Personalmente, no uso AddWithValue, prefiero definir explícitamente los tipos de datos (y tamaños); de lo contrario, puede que se hagan suposiciones incorrectas (como pasar valores de cadena .NET como NVARCHAR) que me vuelven paranoico. – AdaTheDev

0

que hice las cosas que usted está tratando de hacer, aquí algunos ejemplos:

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

Te recomiendo mirar here

y para descargar la solución de muestras (donde hay un proyecto de muestra DAL incluido) http://valueinjecter.codeplex.com/

Cuestiones relacionadas