我正在尝试完成下面的LINQ查询,但我需要一个“不等于”而不是相等,以便filteredEmployees拥有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;
答案 0 :(得分:52)
您不需要加入:
var filteredEmployees = groupA.Except(groupB);
请注意,这将是一系列独特的员工 - 因此,如果groupA
中有任何重复项,则它们只会在filteredEmployees
中显示一次。当然,它还假设你有一个合理的平等比较器 1 。如果您需要专门针对名称,可以使用ExceptBy
中的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 正如评论中所指出的,您可以将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);
答案 1 :(得分:4)
不,“不等于”运算符会获得groupA和groupB的所有组合,除了项目相同的组合。
使用Except方法可以获得您想要的效果:
var filteredEmployees = groupA.Except(groupB);
答案 2 :(得分:3)
在Entity Framework 6中,我使用
获得了更好的结果var filteredEmployees = groupA.Where(a => !groupB.Select(b => b.Name).Contains(a.Name));
答案 3 :(得分:0)
使用此代码可降低服务器成本:
与其他代码相比,该代码的运行速度非常快
var noExistList = (from n in groupA
join o in groupA on n.Id equals o.Id into p
where p.Count() == 0
select n).ToList();
注意:groupA是要添加的新列表。