在内存集合和EntityFramework之间加入

是否有任何机制可以在保留顺序的同时在内存中集合和entity framework之间进行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-to-objects执行连接的情况下,无法使用数据库结果集加入内存中集合。 尝试使用contains而不是join:

 var myNumbers = myInMemoryList.Select(i => i.RECORD_NUMBER); var itemsToAdd = efRepo.Where(e => myNumbers.Contains(e.RECORD_NUMBER)); 

这将使用IN运算符生成查询

您可以在我的博客文章中阅读如何使用LINQKit或存储过程中的PredicateBuilder执行此操作。

http://kalcik.net/2014/01/05/joining-data-in-memory-with-data-in-database-table/

试试这个:

 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);