I am trying accomplish the LINQ query below but I need a "not equal" instead of equal, so that filteredEmployees has all employees from groupA minus 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;
In a LINQ query expression, join operations are performed on object collections. Object collections cannot be "joined" in exactly the same way as two relational tables. In LINQ, explicit join clauses are only required when two source sequences are not tied by any relationship.
In LINQ, an inner join is used to serve a result which contains only those elements from the first data source that appears only one time in the second data source. And if an element of the first data source does not have matching elements, then it will not appear in the result data set.
You don't need a join for that:
var filteredEmployees = groupA.Except(groupB);
Note that this will be a sequence of unique employees - so if there are any duplicates in groupA
, they will only appear once in filteredEmployees
. Of course, it also assumes you've got a reasonable equality comparer1. If you need to go specifically on name, you can use ExceptBy
from MoreLINQ:
var filteredEmployees = groupA.ExceptBy(groupB, employee => employee.Name);
Or without going into a third party library:
var groupBNames = new HashSet<string>(groupB.Select(x => x.Name)); var filteredEmployees = groupA.Where(x => !groupBNames.Contains(x.Name));
1 As pointed out in the comments, you can pass in an IEqualityComparer<T>
as an argument to Except
. I have a ProjectionEqualityComparer
class in MiscUtil which makes it easy to build a comparer of the kind you need:
// 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);
No, a "not equal" operator would get you all combinations of groupA and groupB except the ones where the items were the same.
Using the Except method gets you what you want:
var filteredEmployees = groupA.Except(groupB);
If you love us? You can donate to us via Paypal or buy me a coffee so we can maintain and grow! Thank you!
Donate Us With