J'essaie d'accomplir la requête LINQ ci-dessous mais j'ai besoin d'un "différent" au lieu d'être égal, de sorte que les employés filtrés aient tous les employés du groupe A moins le groupe 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;
Vous n'avez pas besoin d'une jointure pour cela:
var filteredEmployees = groupA.Except(groupB);
Notez que ce sera une séquence d'employés uniques - donc s'il y a des doublons dans groupA
, ils n'apparaîtront qu'une seule fois dans filteredEmployees
. Bien sûr, cela suppose également que vous avez un comparateur d'égalité raisonnable1. Si vous devez aller spécifiquement sur le nom, vous pouvez utiliser ExceptBy
from MoreLINQ :
var filteredEmployees = groupA.ExceptBy(groupB, employee => employee.Name);
Ou sans entrer dans une bibliothèque tierce:
var groupBNames = new HashSet<string>(groupB.Select(x => x.Name));
var filteredEmployees = groupA.Where(x => !groupBNames.Contains(x.Name));
1 Comme indiqué dans les commentaires, vous pouvez passer un IEqualityComparer<T>
comme argument pour Except
. J'ai une classe ProjectionEqualityComparer
dans MiscUtil qui facilite la construction d'un comparateur du type dont vous avez besoin:
// 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);
Non, un opérateur "différent" vous obtiendrait toutes les combinaisons de groupe A et de groupe B, sauf celles où les éléments étaient les mêmes.
L'utilisation de la méthode Except vous permet d'obtenir ce que vous voulez:
var filteredEmployees = groupA.Except(groupB);
Dans Entity Framework 6, j'ai obtenu de meilleurs résultats en utilisant
var filteredEmployees = groupA.Where(a => !groupB.Select(b => b.Name).Contains(a.Name));
utilisation de ce code pour réduire le coût du serveur:
Le code fonctionne très rapidement par rapport à d'autres codes
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();
remarque: groupA est une nouvelle liste à ajouter.