Принудительно выполнить IQueryable? - PullRequest
15 голосов
/ 27 апреля 2009

У меня есть метод, который «не имеет перевода в SQL», который я хочу выполнить на IQueryable, есть ли способ заставить IQueryable выполняться без необходимости сохранять его в каком-то промежуточном классе?

Ответы [ 3 ]

27 голосов
/ 27 апреля 2009

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

public IEnumerable<T> AsEnumerable(IEnumerable<T> source)
{
    return source;
}

Важно то, что он делает тип времени компиляции результата IEnumerable<T>, а не IQueryable<T>, что означает, что все операторы запросов LINQ, которые вы вызываете после этого, будут LINQ to Objects вместо LINQ to SQL.

Например:

var query = context.Employees
                   // Filtering performed in SQL
                   .Where(emp => emp.IsFullTime)
                   .AsEnumerable()
                   // Projection performed locally; ComputeSalary has no
                   // SQL equivalent
                   .Select(emp => new { Employee = emp,
                                        Salary = ComputeSalary(emp) });

Вы можете позвонить ToList, как предложено в другом месте, но если вы выполняете фильтрацию и вам не нужен полный список в памяти, вызываете AsEnumerable и фильтруете , что результат будет более эффективным, чем первая загрузка.

7 голосов
/ 27 апреля 2009
List<Employees> myEmployees =  myqueryable.ToList();

и тогда вы можете делать свои вещи в этом списке.

2 голосов
/ 27 апреля 2009

Вы получаете это сообщение, когда пишете запрос, который LinqToSql не знает, как перевести на SQL (что он тоже говорит).

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

  1. Перепишите ваш запрос, чтобы LinqToSql МОЖЕТ перевести его
  2. Выполните столько запросов, сколько сможете на Sql Server, а затем сделайте все остальное в памяти (используя linq для объектов)
  3. Садись и плачь

Предполагая, что мы исключаем # 3, давайте посмотрим на 2 других примера.

  1. Переписав его - для этого нам понадобится ваш запрос linq.

  2. Здесь вы берете часть, которая не может быть переведена из исходного запроса, затем в ваш вызов Toquist Iqueryable, а затем применяете остальную часть запроса к этому списку.

И можете ли вы выполнить запрос, не сохраняя его? Ну, не совсем, вы всегда можете просмотреть результаты и, следовательно, не сохранять их в переменной, но очевидно, что результаты запроса нужно где-то хранить.

...