linq 连接中是不是存在“不等于”
Posted
技术标签:
【中文标题】linq 连接中是不是存在“不等于”【英文标题】: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;
【问题讨论】:
Using Linq not 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<T>
作为参数传递给 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<Employee>
实现。如果覆盖 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));
【讨论】:
以上是关于linq 连接中是不是存在“不等于”的主要内容,如果未能解决你的问题,请参考以下文章
LINQ 是不是使用 DataRelations 来优化连接?
何时更喜欢用 SelectMany() 表示的连接而不是用 Linq 中的 join 关键字表示的连接
在 Entity Framework Core 中,如何使用数据库级别的条件(不是本地 LINQ)查询连接表上的数据?