IQueryable 或 List 如果有很多查询请求

IQueryable or List if many requests to a query

获取物品有两种选择。 我知道IQueryable有延迟加载,List(.ToList())是立即执行的。 request 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...
}

Will request items.FirstOrDefault() make a request to the database every time you pass the loop

如果项目仍然是 IQueryable,这将通过循环在每次迭代时向数据库发送查询。

如果 items 是 List<T>,那么您已经将所有结果从数据库检索到内存中。因此在循环中调用 FirstOrDefault 只会在内存中的集合中搜索。

哪个更有效取决于很多因素。循环并发出一堆查询通常称为 "chatty API" 并且不受欢迎。如果您可以点击一次并获取内存中的所有数据,然后在那里进行过滤,那么您可能会比所有这些往返数据库更好。

当然,如果结果集巨大,这可能会占用您的应用程序的内存。如果它必须扫描一些 table.

的很大一部分,那么它在数据库方面也可能很糟糕

更好的方法是将其他搜索条件推送到查询中。这似乎可行:

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();