Как защитить мой запрос: я получаю, что SqlParameter уже содержится в другой коллекции SqlParameterCollection

Я пытаюсь параметризовать все запросы, чтобы удовлетворить результаты SQL-инъекций из расширения сканирования уязвимостей PUMA в Visual Studio. При этом я сталкиваюсь с ошибкой в ​​​​заголовке:

SqlParameter уже содержится в другой коллекции SqlParameterCollection.

Это соответствующий код (вторая строка генерирует ошибку):

    IEnumerable<UploadedDocsClass> docLst = prfDao.GetUploadedDocLog(Convert.ToInt32(id));
    if (docLst.Count() > 0){ //<-- this is where the error is thrown
    ...
    }

public IEnumerable<UploadedDocsClass> GetUploadedDocLog(int tickId)
{
  string s = "SELECT * FROM MyTable WHERE [request_id] = @tickId ";
  MyDataBaseContext accCon = new MyDataBaseContext();
  return accCon.Database.SqlQuery<UploadedDocsClass>(s, new SqlParameter("@tickId", Convert.ToString(tickId)));
}

Я искал здесь и в Google и не могу найти решение для моей конкретной ситуации. Я пробовал клонировать параметр, объявив его специально и установив для него значение null после его использования, поместив его в коллекцию перед его использованием, я даже пытался добавить случайное число в конце имени параметра, чтобы оно каждый раз было другим, но ничего, та же ошибка.

Как я могу решить эту проблему, все еще используя параметр в запросе?

Спасибо


person cheluto2    schedule 25.09.2017    source источник
comment
Вы не показали никакого кода, который на самом деле включает SqlParameter.   -  person SLaks    schedule 25.09.2017
comment
Да. Это последняя строка кода в моем примере.   -  person cheluto2    schedule 25.09.2017
comment
Я предполагаю, что он жалуется на то, к чему сводится эта фраза Convert, что означает, что все, что tickID разрешает в этом контексте, может использоваться только одним запросом. Обычно мы видим, что .Clear() используется в таких вещах перед повторным использованием (или созданием нового набора параметров, но я не полностью понимаю этот код (поэтому это не ответ).   -  person    schedule 25.09.2017
comment
Это полностью зависит от того, что делает SqlQuery().   -  person SLaks    schedule 25.09.2017
comment
Т.С. Я починил это. Я упростил текст запроса для этого поста, реальный запрос намного длиннее и использует StringBuilder, ссылку на который я случайно оставил в загруженном тексте.   -  person cheluto2    schedule 25.09.2017
comment
Это потому, что IEnumerable<UploadedDocsClass> вернулся? затем он пытается выполнить снова? Попробуйте вернуть List<T>   -  person T.S.    schedule 25.09.2017
comment
@Т.С. - кажется, дело пошло! Большое спасибо! Если вы сделаете этот комментарий ответом, я буду рад отметить его как решение.   -  person cheluto2    schedule 25.09.2017


Ответы (1)


Это потому, что IEnumerable<UploadedDocsClass> вернулся. Он пытается выполнить снова, когда вызывается docLst.Count() - отличается выполнение

Попробуйте вернуть List<T>

MSDN: запрос не выполняется при создании этого объекта; он выполняется каждый раз при его перечислении, например, с помощью foreach.

Судя по всему, пытается повторно использовать параметры, добавленные в другую коллекцию (предыдущее выполнение)

person T.S.    schedule 25.09.2017
comment
Еще раз спасибо, это именно то, что мне нужно было знать. Я протестировал его, и он работает при возврате как List‹T› - person cheluto2; 25.09.2017
comment
Без проблем. Всегда будьте осторожны с IEnumerable, так как он уводит вас в страну разнообразного исполнения. И DbRawSqlQuery<TElement> тоже - person T.S.; 25.09.2017