IQueryable или список, если много запросов на запрос - PullRequest
0 голосов
/ 20 февраля 2019

Есть два варианта получения предметов.Я знаю, что IQueryable имеет ленивую загрузку, и List (.ToList()) выполняется немедленно.Будет ли items.FirstOrDefault() запрашивать запрос к базе данных каждый раз, когда вы проходите цикл, или только на первой итерации?Или я все еще должен конвертировать в List?

var items = _someDbContext.Items.Where(x => x.Date >= DateTime.Now.Date.AddMonth(-3);//IQueryable<Items> result
var items = _someDbContext.Items.Where(x => x.Date >= DateTime.Now.Date.AddMonth(-3).ToList();//List<Items> result
foreach (var oneData in someData)
{
    var searchedItems = items.FirstOrDefault(x => x.SomeField == oneData.SomeField);
    //...some code...
}

1 Ответ

0 голосов
/ 20 февраля 2019

Запрашивает items.FirstOrDefault () отправляет запрос в базу данных каждый раз, когда вы передаете цикл

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

Если элементы List<T>, то вы уже извлекли все результаты из базы данных в память.Таким образом, вызов FirstOrDefault в цикле будет просто искать в этой коллекции в памяти.

Какой из них более эффективен, будет зависеть от множества факторов.Циклическое выполнение и выдача множества запросов обычно называется «болтливым API» и вызывает неодобрение.Если вы можете принять удар один раз и получить все данные в памяти, а затем отфильтровать их, вам, возможно, будет лучше, чем выполнять все эти поездки в базу данных.

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

Лучшим подходом было бы, если бы вы могли вставить другое условие поиска в запрос.Похоже, это будет работать:

var listOfSomeField = someData.Select(x => x.SomeField).ToList();

var items = _someDbContext.Items
    .Where(x => 
        x.Date >= DateTime.Now.Date.AddMonth(-3)
        && listOfSomeField.Contains(x.SomeField))
    .ToList();
...