Есть ли "не равный" в соединении linq - PullRequest
29 голосов
/ 21 сентября 2010

Я пытаюсь выполнить приведенный ниже запрос LINQ, но мне нужно «не равно» вместо «равно», чтобы в FilterEmployees были все сотрудники группы A минус группа B.

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 ]

52 голосов
/ 21 сентября 2010

Для этого вам не нужно объединяться:

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. У меня есть ProjectionEqualityComparer класс в MiscUtil , который облегчает создание компаратора того типа, который вам нужен:

// 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);
4 голосов
/ 21 сентября 2010

Нет, оператор "не равно" получит вам все комбинации groupA и groupB, за исключением тех, где элементы были одинаковыми.

Использование метода Except дает вам то, что вы хотите:

var filteredEmployees = groupA.Except(groupB);
3 голосов
/ 12 ноября 2014

В Entity Framework 6 я получил лучшие результаты, используя

var filteredEmployees = groupA.Where(a => !groupB.Select(b => b.Name).Contains(a.Name));
0 голосов
/ 20 апреля 2019

использование этого кода для снижения стоимости сервера:

Код работает очень быстро по сравнению с другим кодом

        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();

примечание: группа A являетсяновый список для добавления.

...