2013-07-29 4 views
1

Я ищу, чтобы лучше понять, когда мы должны использовать IEnumerable над IQueryable с LINQ to Entities.LINQ to Entities - Entity Framework

С действительно базовыми вызовами в базу данных, IQueryable быстрее, но когда мне нужно подумать об использовании IEnumerable на своем месте?

Где IEnumerable оптимальный по сравнению с IQueryable?

ответ

5

В принципе, IQueryables выполняется поставщиком запроса (например, базой данных), а некоторые операции не могут быть или не должны выполняться базой данных. Например, если вы хотите вызвать функцию C# (здесь, как пример, запишите имя правильно), используя значение, полученное из базы данных, вы можете попробовать что-то вроде:

db.Users.Select(x => Capitalize(x.Name)) // Tries to make the db call Capitalize. 
     .ToList(); 

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

db.Users.Select(x => x.Name)    // Gets only the name from the database 
     .AsEnumerable()     // Do the rest of the operations in memory 
     .Select(x => Capitalize(x))  // Capitalize in memory 
     .ToList(); 

Самое главное, когда речь идет о выполнении IQueryable против IEnumerable со стороны EF, является то, что вы должны всегда пытаться фильтровать данные, используя IQueryable получить как мало данных, как можно конвертировать в IEnumerable. То, что вызов AsEnumerable в основном заключается в том, чтобы сообщить базе данных «дать мне данные, поскольку они отфильтрованы сейчас», и если вы не отфильтровали их, вы получите все, что извлечено в память, даже данные, которые вам могут не понадобиться.

3

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

IQueryable с другой стороны, представляет собой совокупность элементов, на которых такие операции, как фильтрация могут быть отложены до базового источника данных, так что в случае фильтрации, если бы я реализовать IQueryable на верхней часть пользовательского источника данных (или использовании LINQ to Entities!), То я мог бы приложить тяжелую работу по фильтрации/группировке и т. Д. К источнику данных (например, к базе данных).

Основной недостаток IQueryable заключается в том, что реализация его довольно сложна - запросы построены как деревья выражений, которые, как разработчик, вам необходимо проанализировать, чтобы разрешить запрос. Если вы не планируете писать провайдера, то это не повредит вам.

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

Смежные вопросы