У меня есть проблемы при понимании IQueryable <T>

Таким образом, я пытаюсь понять IQueryable<T>. Учебное руководство, которое я читаю, предлагает использовать его, но не действительно уверенное почему. Код просто возвращает некоторые значения с помощью LINQ для SQL. Я сделал это много времен в прошлом, но не использования IQueryable<T>

Почему использование это с моими функциями, которые возвращают больше чем 1 значение?

Вот мой код:

public IQueryable<Items> GetItems()
    {
        return from item in db.Items
               where item.IsActive == true
               orderby item.ItemNumber
               select item;
    }
14
задан Robert Harvey 19 March 2012 в 16:07
поделиться

2 ответа

IQueryable представляет запрос в виде дерева выражений, не оценивая его на сервере. Это позволяет задать дальнейшую обработку перед тем, как генерировать SQL.

В приведенном выше случае это означает, что вы можете делать разные вещи с результатом вызова GetItems(), и исходный запрос и дополнительные вещи будут отправлены как один запрос:

var recentItems = from item in GetItems()
                  where item.Timestamp > somedate
                  select item;

foreach (var item in recentItems)
{
    // Do something with an active recent item.
}

Ничего не отправляется на сервер, пока мы не попытаемся использовать результат в цикле foreach. В этот момент провайдер LINQ-to-SQL оценивает все выражение, включая части, сгенерированные внутри GetItems(), и части, указанные после, и выдает один SQL-запрос, который выбирает все элементы, которые являются активными и недавними.

Чтобы прояснить один технический момент, IQueryable является IEnumerable, и его поставщик вычисляет окончательный SQL, когда вы пытаетесь вызвать метод GetEnumerator() на нем. Вы можете сделать это либо явно, вызвав его, либо неявно, используя его в операторе foreach. Кроме того, такие методы расширения, как ToArray(), выполняют один из этих методов внутри, что дает тот же эффект.

13
ответ дан 1 December 2019 в 13:32
поделиться

IQueryable (до перечисления) - это не сами результаты, а логика, используемая для возврата этих результатов.

Для примера LINQ2SQL... представьте, что вы возвращаете IQueryable of Clients. Под капотом это будет не список клиентов (пока вы не перечислите их в ToList()), а SQL-запрос следующего вида:

SELECT * FROM [Clients]

Это удобно, потому что мы еще не обратились к базе данных! Итак, допустим, когда IQueriable вернется, мы хотим уточнить его до клиентов по имени "Боб", мы можем сделать следующее:

var clients = GetClients().Where(c => c.Name == "Bob");

Теперь IQueriable выглядит следующим образом:

SELECT * FROM [Clients] WHERE Name = 'Bob'.

Теперь, когда я делаю clients.ToList(), этот запрос будет выполнен, база данных обращена, и у меня есть список клиентов по имени bob без необходимости выбирать всех клиентов, затем перебирать их в памяти или выполнять 2 отдельных обращения к базе данных.

В качестве примера того, как это может аукнуться, попробуйте добраться до дочерних элементов, когда ваш datacontext вышел из области видимости (например, запустите select внутри оператора using). Вот где пригодятся опции загрузки в LINQ2SQL.

Надеюсь, это поможет

.
5
ответ дан 1 December 2019 в 13:32
поделиться
Другие вопросы по тегам:

Похожие вопросы: