У меня проблемы с пониманием IQueryable <T> - PullRequest
14 голосов
/ 18 июля 2010

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

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

Вот мой код:

public IQueryable<Items> GetItems()
    {
        return from item in db.Items
               where item.IsActive == true
               orderby item.ItemNumber
               select item;
    }

Ответы [ 2 ]

13 голосов
/ 18 июля 2010

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<T> - это IEnumerable<T>, и его поставщик вычисляет окончательный SQL, когда вы пытаетесь вызвать для него метод GetEnumerator().Вы можете сделать это явно, вызвав его, или неявно, используя его в операторе foreach.Кроме того, методы расширения, такие как ToArray(), сделают один из них внутренне, что даст тот же эффект.

5 голосов
/ 18 июля 2010

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, при этом мне не нужно было выбирать всех клиентов, а затем просматривать их в памяти или выполнять два попадания в базу данных.

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

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

Добро пожаловать на сайт PullRequest, где вы можете задавать вопросы и получать ответы от других членов сообщества.
...