c# - LINQ to Entities .Contains 元组(2 个外键)

标签 c# entity-framework linq

其实,我的一个同事问过我这个问题,我一直没能想出答案。开始吧。

给定一个有 2 个外键的实体,假设

public class MyTable
{
   public int Key1 { get; set; }
   public int Key2 { get; set; }
}

和 2 个列表

public ICollection List1 => new List<int> { 1, 2, 3 };
public ICollection List2 => new List<int> { 4, 5, 6 };

他需要查询 Key1 与 List1 的值匹配且 Key2 与 List2 的值匹配的所有记录,例如

Key1 == 1 && Key2 == 4

也就是说,他想检查 List1 和 List2 中的任何给定元组,(1, 4),(2, 5) 和 (3, 6)。

EF 中是否有直接的方法来执行此操作?

最佳答案

您可以制作一个for 循环来捕获Where 中的一些局部变量(在每个循环中)并使用Concat(或Union - 可能性能更差)总结所有结果如下:

IQueryable<MyTable> q = null;   
//suppose 2 lists have the same count
for(var i = 0; i < list1.Count; i++){
   var k1 = list1[i];
   var k2 = list2[i];
   var s = context.myTables.Where(e => e.Key1 == k1 && e.Key2 == k2); 
   q = q == null ? s : q.Concat(s);
}
//materialize the result
var result = q.ToList();

注意:我们可以在这里使用Concat,因为每个子结果应该是唯一的(基于搜索键)。它肯定比 Union 具有更好的性能(确保唯一性,而我们事先已经知道子结果都是唯一的 - 所以这是不必要的)。

如果你有一个 int 的列表(只是整型数字),你也可以将键配对成下划线分隔的字符串,并通常像这样使用 Contains:

var stringKeys = list1.Select((e,i) => e + "_" + list2[i]).ToList();
var result = context.myTables.Where(e => stringKeys.Contains(e.Key1 + "_" + e.Key2))
            .ToList();

构建表达式树也是另一种方法,但它更复杂,我不确定它是否具有更好的性能。

关于c# - LINQ to Entities .Contains 元组(2 个外键),我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/32775796/

相关文章:

c# - 抛出 InvalidOperationException 是因为它无法将值从 appsettings.json 转换为枚举

c# - 解析确切的自定义时间格式?

c# - XAML ListView ItemContainer 高度

c# - 添加时 Entity Framework SaveChanges

entity-framework - Entity Framework 4.1 中缺少 DeleteObject 方法

c# - 无法在静态上下文中访问非静态方法?

entity-framework - 如何从 EF5 降级到 EF4?

c# - 在 c# (LINQ-2-Entities) 中实现 "IN"的自定义扩展函数

c# - VB 中的 LINQ C# 查询 - 出现错误

c# - 如何正确使用 distinct 和 compare?