влияет ли размещение запроса Linq внутри метода на отложенное выполнение?

#c# #linq #deferred-execution

#c# #linq #отложенное выполнение

Вопрос:

Запрос Linq не выполняется до тех пор, пока последовательность, возвращаемая запросом, фактически не будет повторена.

У меня есть запрос, который используется неоднократно, поэтому я собираюсь инкапсулировать его внутри метода. Я хотел бы знать, мешает ли это отложенному выполнению.
Если я инкапсулирую запрос Linq в метод, подобный приведенному ниже, запрос выполняется в строке 2, а не в строке 1, где вызывается метод. Правильно ли это?

 public IEnumerable<Person> GetOldPeopleQuery()
{
   return personList.Where(p => p.Age > 60);
}

public void SomeOtherMethod()
{
   var getWomenQuery = GetOldPeopleQuery().Where(p => p.Gender == "F"); //line 1
   int numberOfOldWomen = getWomanQuery.Count();  //line 2
}
  

P.S. Я использую Linq-To-EF, если это имеет какое-либо значение.

Ответ №1:

Запрос вычисляется с задержкой при первом перечислении результата, на который не влияет помещение его внутрь метода.

Однако в вашем коде есть еще одна вещь, которая будет очень неэффективной. Как только вы вернете IEnumerable , следующим оператором linq, применяемым к коллекции, будет запрос linq-to-objects. Это означает, что в вашем случае вы будете загружать всех пожилых людей из базы данных, а затем отфильтровывать женщин в памяти. То же самое с подсчетом, это будет сделано в памяти.

Если вы вместо этого вернете IQueryable<Person> , эти два вопроса будут оценены с использованием linq-to-entities, а фильтрация и суммирование могут быть выполнены в базе данных.

Комментарии:

1. В этом вопросе нет указаний на то, что на самом деле задействована база данных. Но если это так, я согласен с вами о неэффективности.

2. Спасибо! поэтому я буду использовать IQueryable<T> вместо этого.