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

у меня есть следующий код.

// Get total row count and build Pagination object
var countQuery = ArticleServerContext.Database.SqlQuery<int>("GetFullTextSearchCount @SearchTerm",
    new SqlParameter("@SearchTerm", fullTextQuery));
Pagination pagination = new Pagination(countQuery.Single(), page ?? 1);
// Get search results for current page
var resultsQuery = ArticleServerContext.Database.SqlQuery<ArticleSummary>("GetFullTextSearchResults @SearchTerm, @SkipRows, @TakeRows",
    new SqlParameter("@SearchTerm", fullTextQuery),
    new SqlParameter("@SkipRows", pagination.SkippedRows),
    new SqlParameter("@TakeRows", pagination.RowsPerPage));
// Build model
SearchResultsModel model = new SearchResultsModel
{
    SearchTerm = searchTerm.Trim(),
    Pagination = pagination,
    Results = resultsQuery.ToList()   // <=== Here's where the error happens
};

когда я пытаюсь перечислить resultsQuery, Я получаю следующее сообщение об ошибке.

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

это сообщение об ошибке кажется достаточно ясным, но я не вижу, где я добавляю SqlParameter для более чем одного что-нибудь. Единственное, что я могу себе представить, это то, что первый параметр для обоих вызовов идентичен. Может ли C# быть как-то их объединить? В любом случае, мне нужно, чтобы они содержали те же данные.

кто-нибудь видит, что здесь происходит?

EDIT:

извините, это оказалось проблемой отладки. У меня была еще одна проблема, которая помешала ожидаемым результатам. Но когда я ломаю отладчик и шагаю через свой код, я получаю ошибку, упомянутую выше.

кажется, что код выполняется с помощью SqlParameter в вопросе, а затем я пытаюсь проверить содержание запроса и запрос выполняется снова с тем же SqlParameter и это является причиной ошибки.

к сожалению, теперь, когда у меня есть щедрость, я не могу удалить вопрос.

3 ответов


У меня не было хорошего понимания того, что происходило, когда я отвечал на этот вопрос. После дальнейшего изучения выясняется, что:

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

  2. используя отладчик Visual Studio, я установил точку останова в этом коде. Когда я вошел, запросы уже выполнялись. Но затем, когда я пытаюсь проверить данные, это вызвало выполнение запросов снова. Именно это двойное выполнение вызвало ошибку, о которой я сообщил. На самом деле эта ошибка не возникает, когда код выполняется нормально.

спасибо всем, кто взял время, чтобы посмотреть на этот вопрос.


очистите параметры перед их определением: -

cmd.Parameters.Clear()

попробуйте это. Вместо :

  var resultsQuery = ArticleServerContext.Database.SqlQuery<ArticleSummary>("GetFullTextSearchResults @SearchTerm, @SkipRows, @TakeRows",
    new SqlParameter("@SearchTerm", fullTextQuery),
    new SqlParameter("@SkipRows", pagination.SkippedRows),
    new SqlParameter("@TakeRows", pagination.RowsPerPage));
// Build model
SearchResultsModel model = new SearchResultsModel
{
    SearchTerm = searchTerm.Trim(),
    Pagination = pagination,
    Results = resultsQuery.ToList()   // <=== Here's where the error happens
};

использование:

      var results = ArticleServerContext.Database.SqlQuery<ArticleSummary>("GetFullTextSearchResults @SearchTerm, @SkipRows, @TakeRows",
    new SqlParameter("@SearchTerm", fullTextQuery),
    new SqlParameter("@SkipRows", pagination.SkippedRows),
    new SqlParameter("@TakeRows", pagination.RowsPerPage)).ToList();
// Build model
SearchResultsModel model = new SearchResultsModel
{
    SearchTerm = searchTerm.Trim(),
    Pagination = pagination,
    Results = results   // <=== Moved the call to ToList UP
};

Defferred Query исполнение-еще одна причина, по которой я не поклонник EF. Перемещая вызов ToList (), вы заставляете EF выполнять Немедленному Исполнению. В обновлении вашего вопроса Вы заявляете, что ваша проблема связана с проблемой отладки IDE, дважды перезапускающей ваш запрос (вызывающей исключение повторяющегося параметра).

, ваш проблемы отладки можно избежать, обойдя выполнение запроса Defferred и заставив выполнение произойти немедленно, тем самым изменив содержимое переменной resultsQuery из запроса, ожидающего вызова в фактический результирующий набор.

чтобы быть ясным, перемещение вызова ToList () заставляет немедленное выполнение запроса в переменную "resultsQuery", которая изменяет его содержимое (и из-за этого я изменил имя переменной, чтобы отразить ее измененное содержимое). Переменная теперь будет содержать возвращенные результаты вашего запроса, а не сам запрос. Поэтому, когда вы перечисляете над ним, когда выполнение приостановлено, вы будете перечислять над статический список возвращенных результатов, вместо повторный запрос. Таким образом, это предотвратит создание исключения.

вот почему я заявил в своем комментарии, что эта проблема никогда не случалась со мной (кроме того, что я избегаю EF, когда это возможно настоящее время.)

вы можете прочитать больше на MSDN здесь:

https://msdn.microsoft.com/en-us/library/bb738633%28v=vs.100%29.aspx?f=255&MSPPError=-2147217396

из приведенной выше ссылки Microsoft заявляет:

для принудительного немедленного выполнения запроса, который не создает одноэлементное значение, можно вызвать в список методом ToDictionary метод, или метод toArray метод запроса или переменная запроса.