Хорошо, если вы используете Entity Framework (из тегов).
Когда вы выполняете выражение Linq
, вы получаете коллекцию IQueryable
. Это IQueryable
не является правдивой коллекцией, хранящейся в памяти со всеми записями, извлеченными из БД, это своего рода утверждение, куда обращаться к серверу базы данных. Я имею в виду, что вы не будете запрашивать базу данных, так как к этому IQueryable
обращаетесь.
Доступ к коллекции IQueryable
можно получить с помощью итерации или приведения к ней (например, IList
, Array
, ...).
/// This will yield item by item trough the loop.
IQueryable followers = /* linq expression */
foreach (var follower in followers)
{
// ...
}
Вышеупомянутый блок имеет чуть лучшую производительность.
IQueryable followers = /* linq expression */
IList list = followers.ToList(); // At this point, the query is executed in the database server
foreach (var follower in list)
{
// ...
}
Хотя это устройство более безопасно.
Обычная практика - бросать IQueryable
на IList
или аналогичный для предотвращения проблем параллелизма, проблем с потоками и т. Д. c.
Важным моментом является "поиск" IQueryable
после выполнения всех действий в запросе. (фильтрация, сортировка, ...).
Имея IQueryable
примерно так
IQueryable followers = project.Followers;
, теперь вы можете добавлять действия к IQueryable
без затрат памяти или производительности.
followers = followers.Where(/* Any Func<Type, bool> action here*/);
followers = followers.OrderBy(/* Property KeySelector... */);
Как только весь запрос построен, запрос может быть выполнен.
IList realDataInMemory = followers.ToList();
Если вы вызываете метод #ToList
на первом шаге.
IList followers = project.Followers.ToList();
следующие Linq
выражения будут выполняться в коллекции в памяти.