内存中集合和EntityFramework之间的联接
本文关键字:之间 EntityFramework 集合 内存 | 更新日期: 2023-09-27 18:00:57
是否有任何机制可以在内存中的集合和实体框架之间执行JOIN,同时保留顺序。
我正在尝试的是
var itemsToAdd =
myInMemoryList.Join(efRepo.All(), listitem => listitem.RECORD_NUMBER,
efRepoItem => efRepoItem.RECORD_NUMBER, (left, right) => right);
这给了我一个标题很奇怪的错误:"这个方法支持LINQ to Entities基础设施,不打算直接从代码中使用。"。
现在我当然可以用这样的东西反复地做这件事了
foreach (var item in myInMemoryList)
{
var ho = efRepo.Where(h => h.RECORD_NUMBER == item.RECORD_NUMBER).FirstOrDefault();
tmp.Add(ho);
}
但是这是N+1查询。这是令人讨厌的,因为myInMemoryList可能相当大!
Resharper可以为我重构到
tmp = (from TypeOfItemInTheList item in myInMemoryList
select efRepo.Where(h => h.RECORD_NUMBER == item.RECORD_NUMBER)
.FirstOrDefault());
我怀疑它仍在进行N+1查询。因此,找到一种更好的方法来获得与内存中集合匹配(在关键字段上(的ef实体的想法。结果集的顺序必须与内存中集合的顺序相同。
否,如果不将整个结果集加载到内存中并使用linq对对象执行连接,则无法使用数据库结果集连接内存集合。尝试使用包含而不是联接:
var myNumbers = myInMemoryList.Select(i => i.RECORD_NUMBER);
var itemsToAdd = efRepo.Where(e => myNumbers.Contains(e.RECORD_NUMBER));
这将使用IN
运算符生成查询
试试这个:
var list = (from n in efRepo
where myInMemoryList.Select(m=>m.RECORD_NUMBER).Contains(n.RECORD_NUMBER)
select n).ToList();
Contains
将在SQL中转换为IN
运算符(仅当您的RECORD_NUMBER
成员是基元类型,如int
、string
、Guid
等(
加载整个efRepo怎么样?我的意思是这样的(ToArray(((:
var itemsToAdd = myInMemoryList.Join(
efRepo.ToArray(),
listitem => listitem.RECORD_NUMBER, efRepoItem => efRepoItem.RECORD_NUMBER, (left, right) => right);