【问题标题】:Is there a "not equal" in a linq joinlinq 连接中是否存在“不等于”
【发布时间】:2011-04-15 08:10:40
【问题描述】:

我正在尝试完成下面的 LINQ 查询,但我需要一个“不等于”而不是等于,以便过滤员工拥有来自 groupA 减去 groupB 的所有员工。

List<Employee> groupA = getEmployeeA();
List<Employee> groupB = getEmployeeB();        

var filteredEmployees = from a in groupA 
                        join b in groupB on a.Name equals b.Name
                        select a;

【问题讨论】:

标签: linq join equals


【解决方案1】:

您不需要加入:

var filteredEmployees = groupA.Except(groupB);

请注意,这将是一系列独特的员工 - 因此,如果 groupA 中有任何重复项,它们只会在 filteredEmployees 中出现一次。当然,它还假设您有一个合理的相等比较器1。如果需要专门去名字,可以使用ExceptBy from MoreLINQ:

var filteredEmployees = groupA.ExceptBy(groupB, employee => employee.Name);

或者不进入第三方库:

var groupBNames = new HashSet<string>(groupB.Select(x => x.Name));
var filteredEmployees = groupA.Where(x => !groupBNames.Contains(x.Name));

1 正如 cmets 中所指出的,您可以将 IEqualityComparer&lt;T&gt; 作为参数传递给 Except。我在MiscUtil 中有一个ProjectionEqualityComparer 类,可以轻松构建您需要的比较器:

// I can't remember the exact method name, but it's like this :)
var comparer = ProjectionEqualityComparer<Employee>.Create(x => x.Name);
var filteredEmployees = groupA.Except(groupB, comparer);

【讨论】:

  • @Robert 请注意:您可以为Except 的重载提供IEqualityComparer&lt;Employee&gt; 实现。如果覆盖 Equals/GetHashCode (a) 不可能或 (b) 不可取,则很有用。
  • 谢谢。你写的第三个选项成功了。我之前尝试过 IEqualityComparer,但它不起作用。
  • 我喜欢没有第 3 方的 hashset 方法。这很漂亮。
  • 可能需要加入说我有两个表员工和部门,我想通过部门的主键将员工与部门联系起来,但是部门和员工都有列费用,我希望员工费用不等于部门费用的结果(AND 操作)
  • @VISHMAY:这远远超出了 OP 的要求。
【解决方案2】:

不,“不等于”运算符将为您提供 groupA 和 groupB 的所有组合,但项目相同的组合除外。

使用 except 方法可以得到你想要的:

var filteredEmployees = groupA.Except(groupB);

【讨论】:

    【解决方案3】:

    在 Entity Framework 6 中,我使用

    获得了更好的结果
    var filteredEmployees = groupA.Where(a => !groupB.Select(b => b.Name).Contains(a.Name));
    

    【讨论】:

      猜你喜欢
      • 2022-01-11
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      • 2015-09-24
      • 1970-01-01
      • 1970-01-01
      • 2017-09-05
      相关资源
      最近更新 更多