Ошибка: Результат запроса нельзя перечислить более одного раза

Вызов SP в EF 4.0 в следующем коде:

  public IQueryable<Employee> GetEmployeesByFollowup()
        {
            var results = from p in this.ObjectContext.SearchEmployeeFollowup()
                          select p;
            foreach (Employee p in results)
            {
                p.DepaermentReference.Load();                
            }
            return results.AsQueryable<Employee>();
        }

Следующая ошибка, вызванная циклом For:

"Результат запроса не может быть пронумерован более одного раза."} System.SystemException {System.InvalidOperationException}

Вроде работает нормально какое-то время. Не понимаю почему.


person KentZhou    schedule 20.07.2010    source источник


Ответы (3)


Возврат IQueryable из метода полезен только в том случае, если вы хотите что-то добавить к запросу (фильтр, проекция, соединение...) перед его выполнением. Но поскольку ваш метод перечисляет результаты с помощью foreach, запрос уже был выполнен, когда вы его возвращаете, поэтому слишком поздно что-либо добавлять к нему...

Возможно, вместо этого ваш метод должен возвращать IEnumerable<Employee>:

    public IEnumerable<Employee> GetEmployeesByFollowup()
    {
        var results = this.ObjectContext.SearchEmployeeFollowup().ToList();
        foreach (Employee p in results)
        {
            p.DepaermentReference.Load();
        }
        return results;
    }

Кстати, EF 4.0 обрабатывает ленивую загрузку связанных сущностей, поэтому обычно вам не нужно явно вызывать Load

person Thomas Levesque    schedule 20.07.2010
comment
вы правы, если вы используете ObjectSet, нет необходимости явно загружать ссылку для вызова Load(), Include выполнит эту работу. Но когда вы можете использовать хранимую процедуру и сопоставить результат с EntitySet(ResultSet), вам необходимо явно загрузить ссылку. Попытаюсь. Странная вещь: код работает нормально в первый раз, когда это делается, но позже возникает ошибка выше. Действительно запутался. Спасибо. - person KentZhou; 21.07.2010
comment
Попробуйте код выше, измените IQuerable на IEnumerable, все равно получите то же сообщение об ошибке: результат запроса не может быть пронумерован более одного раза. - person KentZhou; 21.07.2010
comment
Ошибка возникает в цикле foreach. Как возвращаемое значение рассматриваемого метода имеет отношение к строке foreach? - person Ashish Gupta; 29.08.2010

Если вы на самом деле не используете интерфейс IQueryable, простым решением будет вызвать .ToList() и работать с типом возврата IEnumerable или List.

person Chathuranga Wijeratna    schedule 10.09.2011

public IEnumerable<Employee> GetEmployeesByFollowup()
{
    var results = this.ObjectContext.SearchEmployeeFollowup().ToList();
    foreach (Employee p in results.ToList())
    {
        p.DepaermentReference.Load();
    }
    return (IEnumerable<Employee>)results;
}

в цикле foreach попробуйте преобразовать results.ToList() смешно, но в моем случае работает.

person lahyaw    schedule 14.12.2011