Entity Framework перечисляет результат SqlQuery

У меня странная ошибка, когда я пытаюсь просмотреть результаты SqlQuery:

var sql = "SELECT @someParam";
var someParamSqlParameter = new SqlParameter("someParam", "Some Value");
var result = _dbContext.SqlQuery<string>(sql, someParamSqlParameter);
var containsAnyElements = result.Any();

Поэтому, когда отладчик находится в последней строке и когда я пытаюсь развернуть представление результатов result, он показывает мне ожидаемое result("Some Value"), но при вызове последней строки я получил исключение

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

Похоже, когда я пытаюсь открыть представление результатов result, он снова вызывает этот запрос. Правильно ли это поведение? Если да, объясните, почему это происходит.


person Vladimirs    schedule 02.04.2013    source источник


Ответы (1)


Похоже, когда я пытаюсь открыть представление результатов, он снова вызывает этот запрос.

Вы совершенно правы — вы видите эффекты Deferred Execution.

Database.SqlQuery<T> возвращает IEnumerable<T>, который на самом деле является объектом типа:

System.Data.Entity.Internal.InternalSqlQuery<T>

Таким образом, ваш объект result на самом деле представляет собой просто описание запроса, а не результаты запроса.

Запрос SQL фактически выполняется в базе данных только тогда, когда вы пытаетесь просмотреть результаты запроса.

Вы видите, что это происходит дважды: один раз, когда ваш код вызывает .Any(), и один раз, когда отладчик перечисляет набор результатов.


Вы можете исправить это, явно указав EF, когда выполнять запрос с .ToList():

var result = _dbContext.SqlQuery<string>(sql, someParamSqlParameter).ToList();

Тип result теперь List<string> и содержит результаты вашего запроса.

person Nick Butler    schedule 02.04.2013
comment
Отличное объяснение. Большое спасибо за столь быстрый и четкий ответ. - person Vladimirs; 02.04.2013
comment
Отличный друг. Я сходил с ума, и все остальные ответы на ту же тему ничем не помогли. - person alessalessio; 08.12.2015
comment
Я не могу понять, как эта проблема вызвала сообщение об ошибке, о котором сообщалось. - person Jonathan Wood; 20.06.2016
comment
Серьезно... Я только что провел 6 часов... и ответ - идти .ToList()?? Замечательный! - person Fred; 28.03.2017