内存中集合和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实体的想法。结果集的顺序必须与内存中集合的顺序相同。

内存中集合和EntityFramework之间的联接

否,如果不将整个结果集加载到内存中并使用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成员是基元类型,如intstringGuid等(

加载整个efRepo怎么样?我的意思是这样的(ToArray(((:

var itemsToAdd = myInMemoryList.Join(
    efRepo.ToArray(),
    listitem => listitem.RECORD_NUMBER, efRepoItem => efRepoItem.RECORD_NUMBER, (left, right) => right);