在内存集合和EntityFramework之间加入

And*_*iih 15 c# linq linq-to-entities entity-framework join

是否有任何机制可以在保留订单的同时在内存中集合和实体框架之间进行JOIN.

我在想的是

var itemsToAdd = 
  myInMemoryList.Join(efRepo.All(), listitem => listitem.RECORD_NUMBER,
  efRepoItem => efRepoItem.RECORD_NUMBER, (left, right) => right);
Run Code Online (Sandbox Code Playgroud)

这给了我一个相当奇怪的标题"这个方法支持LINQ to Entities基础结构,而不是直接在你的代码中使用." 错误.

当然,我可以用类似的东西迭代地做到这一点

        foreach (var item in myInMemoryList)
        {
            var ho = efRepo.Where(h => h.RECORD_NUMBER == item.RECORD_NUMBER).FirstOrDefault();
            tmp.Add(ho);
        }
Run Code Online (Sandbox Code Playgroud)

但这是一个N + 1查询.哪个是讨厌的,因为myInMemoryList可能非常大!

Resharper可以为我重构

        tmp = (from TypeOfItemInTheList item in myInMemoryList 
           select efRepo.Where(h => h.RECORD_NUMBER == item.RECORD_NUMBER)
           .FirstOrDefault());
Run Code Online (Sandbox Code Playgroud)

我怀疑它仍在进行N + 1次查询.因此,有任何想法可以更好地获取与关键字段匹配的ef实体与内存中集合.结果集必须与内存中集合的顺序相同.

Lad*_*nka 18

否,您无法在不将整个结果集加载到内存并使用linq-to-objects执行连接的情况下,无法使用数据库结果集加入内存中集合.尝试使用contains而不是join:

var myNumbers = myInMemoryList.Select(i => i.RECORD_NUMBER);
var itemsToAdd = efRepo.Where(e => myNumbers.Contains(e.RECORD_NUMBER));
Run Code Online (Sandbox Code Playgroud)

这将生成与IN运算符的查询