IEnumerable: используйте , когда вы имеете дело с коллекциями объектов в памяти процесса и перебираете объекты коллекции. Обеспечивает прямое представление данных в памяти.

IEnumerable ‹EmpDetails› empDetails

= empEntity.EmpDetails.where (a = ›a.firstname.contains (« Ra »));

// Немедленно выполняется

empDetails = empDetails.Take (1); // в памяти

int count = empDetails.count (); // в памяти

Вышеупомянутый запрос, выполняемый в БД, - select EmpDetails с именем «Ra» без Top One и функции Count. Все данные о сотрудниках передаются из БД в приложение и помещаются в память приложения, где мы применяем Top и операция подсчета.

IEnumerable использует объекты Func, что приводит к тому, что запрос выполняется немедленно и полностью, ваше приложение получит повышение производительности.

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

IQueryable ‹EmpDetails› empDetailsVar =

empEntity.EmpDetails.where (a = ›a.firstname.contains (« Ra »));

empDetailsVar = empDetailsVar.Take (1); // Отложенное выполнение

int count = empDetailsVar.count () // Теперь выполняется

Вышеупомянутый запрос, выполняемый в БД, - это select EmpDetails с именем «Ra» с функцией Top и Count. После применения top и подсчета данных он будет отправлен в приложение.

Компромисс заключается в том, что вы экономите память и некоторую пропускную способность сети в обмен на более длительное время перечисления. IQueryable использует объекты Expression, которые приводят к тому, что запрос выполняется только тогда, когда приложение запрашивает перечисление .

Используйте IQueryable, когда вам нужно выполнять специальные запросы к источникам данных, таким как LinQ to SQL Server, Entity framework и другим источникам, которые реализуют IQueryable.

Другой пример:

Список отделов и сотрудников (людей), работающих в этих отделах.

db.Departments.Select (c = ›new {Name = c.Name,
Boss = c.Employee.FirstOrDefault (e =› e.IsDepartmentHead) .Name)}
) .ToList ();

db.Departments. ToList () .Select (c = ›new {Name = c.Name,
Boss = c.Employee.FirstOrDefault (e =› e.IsDepartmentHead) .Name)}
) .ToList ();
Но сейчас мы опрашиваем все отделы, а затем преобразовали результат в список в памяти. И вложенный запрос для главы отдела выполняется в коде, а не в базе данных.
Это может сработать для небольших наборов данных, но почему это делается в памяти, а не как запрос?

В чем разница?

Разница заключается в типах и сигнатурах двух разных функций Select этих двух типов.
В случае запроса linq чистой среды сущностей типом является IQueryable, когда мы помещаем ToList() перед Select(), мы вместо этого получаем IEnumerable.

Когда у нас есть IEnumerable, Select - это функция, которая принимает аргумент Func<TSource, TResult>as, когда у нас есть IQueryable, тогда Select вместо этого ожидает аргумент Expression<Func<TSource, TResult>>.

Другими словами:
Аргумент, который мы передаем оператору Select при выполнении запроса Entity Framework Linq, - это не код, который фактически выполняется, а объект выражения. Этот объект выражения используется для описания Entity Framework запрос, который мы хотим создать.