Почему использование Count с IQueryable считается неосуществимым

Если у меня есть следующий код: -

IQueryable<People> list = repository.FindAllPeople;  
int count = list.Count(); 

Тогда считается ли невозможным считать объекты IQueryable, и лучше использовать IEnumerable? BR

Ответ 1

Вы были дезинформированы.

IEnumerable будет использовать Linq для объектов, все методы выполняются на объектах в памяти. - IQueryable будет использовать любую реализацию методов расширения Linq, предоставляемую конкретным провайдером. В этом случае (репозиторий) я бы предположил, что скорее всего поставщик, который отображает выражения Linq в операторы базы данных.

Это означает, что если вы используете IQueryable:

IQueryable<People> list = repository.FindAllPeople;  
int count = list.Count(); 

Счет определяется в самой базе данных, то есть в качестве запроса "select count(*) from People". Это обычно очень, очень быстро.

Если вы используете IEnumerable:

IEnumerable<People> list = repository.FindAllPeople;  
int count = list.Count(); 

Все экземпляры People будут материализоваться в память один за другим, в то время как Linq для объектов выполняет итерацию через коллекцию, чтобы определить счетчик. Это будет очень медленно, и его следует избегать, когда это возможно.

Поскольку не все вызовы методов могут быть сопоставлены с запросами базы данных, иногда невозможно использовать IEnumerable, но всякая фильтрация, объединение и группировка должны выполняться на IQueryable, если это возможно, а затем в качестве последнего шага вы можете использовать AsEnumerable() методы расширения для переключения на использование IEnumerable и Linq для объектов.

Ответ 2

Я не знаком с неосуществимостью IQueryable, но этот пост в блоге, похоже, указывает на то, что IQueryable гораздо предпочтительнее IEnumerable, потому что IQueryable позволяет получить доступ к основному выражению.

Это может быть актуальным только в случае предложения Where и не влияет на .Count().