在linq连接中是否存在“不相等”

时间:2010-09-21 17:32:00

标签: linq join equals

我正在尝试完成下面的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;

4 个答案:

答案 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是要添加的新列表。