IQueryable或列出查询的许多请求

时间:2019-02-20 17:06:30

标签: c# list linq-to-sql iqueryable

有两种获取物品的选项。 我知道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 :(得分: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();