有两种获取物品的选项。
我知道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...
}
答案 0 :(得分:1)
会请求项目。每次传递循环时,FirstOrDefault()都会向数据库发出请求
如果items仍然是IQueryable
,则在每次循环遍历时,都会向数据库发送查询。
如果items是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();