Подтвердить что ты не робот

Преобразование запроса IQueryable linq в IEnumerable <T> отменяет оптимизированный способ linq для работы?

Я новичок в .NET, и мне было интересно, как работает linq, поскольку вы можете использовать множество запросов linq один за другим, но ни один из них не выполняется, пока они не используются для передачи информации или конвертирования список и т.д.
Существует два важных способа получить запрос linq, используя IQueryable<T>, который использует фильтры, которые непосредственно связаны с Sql и IEnumerable, которые получают все записи, а затем работают с ними в памяти. Однако давайте взглянем на этот код:

            //Linq dynamic library
            IQueryable<Table> myResult = db.Categories
                .Where(a => a.Name.Contains(StringName))
                .OrderBy("Name")
                .Skip(0)
                .Take(10);

            if (myResult != null)
            {
                return myResult.AsEnumerable();
            } 
            else
            { return null; }

Depsite Я использую динамическую библиотеку Linq, прямой результат этого запроса находится на IQueryable<T>, если запрос, наконец, возвращается как IEnumerable, является ли запрос действительно фильтрованным на sql? или это в памяти?

4b9b3361

Ответ 1

Он по-прежнему будет выполняться в базе данных, не волнуйтесь. В основном это все, до которого используется реализация Where и т.д. Пока вы вызываете методы на IQueryable<T> - с помощью методов расширения Queryable - он будет использовать деревья выражений. Когда вы начнете извлекать из этого запроса, он будет преобразован в SQL и отправлен в базу данных.

С другой стороны, если вы используете любой из этих методов после того, как вы получили его как IEnumerable<T> (с точки зрения типа времени компиляции), который будет использовать методы расширения в Enumerable, и все остальной части обработки будет выполняться в процессе.

В качестве примера рассмотрим следующее:

var query = db.People
              .Where(x => x.Name.StartsWith("J"))
              .AsEnumerable()
              .Where(x => x.Age > 20);

Здесь AsEnumerable() просто возвращает свою входную последовательность, но набирается как IEnumerable<T>. В этом случае запрос базы данных будет возвращать только людей, имя которых начиналось с J - и тогда фильтрация возраста была бы сделана на клиенте вместо этого.

Ответ 2

Если вы возвращаете IEnumerable<T>, а затем уточняете запрос, то дальнейшая уточнение происходит в памяти. Часть, выраженная в IQueryable<T>, будет переведена в соответствующие утверждения SQL (для случая LINQ-to-SQL, очевидно).

См. Возврат IEnumerable <T> vs. IQueryable <T> для более подробного ответа.