2010-05-06 3 views
7

У меня проблема с частью кода. Я передаю параметр (List<SqlParameter>) методу, выполняющему следующий код.SqlCommand.Parameters.AddWithValue issue: Процедура или функция X ожидает параметр @Y, который не был отправлен

Когда он запускает 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(); 
     } 

ответ

10

ли .Value набор для null для любого из параметров? Если это так, они не отправляются. Попробуйте:

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

(обратите внимание, что нуль-сливающийся с DBNull.Value)

Кроме того, обратите внимание, что AddWithValue может повлиять на ваш запрос план повторного использование, так как (для строк и т.д.) он использует длину значение. Если вам нужна максимальная производительность, лучше настроить параметр вручную с помощью , определяемых размерами.

Также обратите внимание, что потенциально некоторые из параметров входящего списка могут быть вход-вывод, вывод или результат. Я бы очень хотелось, чтобы заменить на что-то подобное:

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

+1. Я лично не использую AddWithValue, предпочитая явно определять типы данных (и размеры). В противном случае могут возникнуть ошибочные предположения (такие как значения строки .NET, передаваемые как NVARCHAR), которые я получаю параноидальными – AdaTheDev

0

Я сделал вещи, которые вы пытаетесь сделать, вот некоторые примеры:

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

Я рекомендую вам посмотреть here

и загрузить образцовое решение (там, где имеется проект DAL Sample). http://valueinjecter.codeplex.com/

Смежные вопросы