2010-09-08 8 views
6

J'ai 2 collections de liste dans mon C# app..A et B.LINQ est égal à ne pas

Les deux collections ont l'objet client qui a identification et le nom attributes.Typically, A a plus d'éléments que B.

En utilisant Linq, je souhaite renvoyer uniquement les clients dont l'ID est dans A mais pas dans B.

Comment procéder?

+0

Que voulez-vous dire, "se joindre à une condition de non égalité"? –

+0

pouvez-vous rendre votre question un peu plus spécifique? – FosterZ

Répondre

18

Il existe plusieurs approches à adopter. L'approche la plus propre consiste à utiliser la méthode d'extension Except si vous avez dépassé Equals et GetHashCode. Si ce n'est pas le cas, il existe d'autres options.

// have you overriden Equals/GetHashCode? 
IEnumerable<Customer> resultsA = listA.Except(listB); 

// no override of Equals/GetHashCode? Can you provide an IEqualityComparer<Customer>? 
IEnumerable<Customer> resultsB = listA.Except(listB, new CustomerComparer()); // Comparer shown below 

// no override of Equals/GetHashCode + no IEqualityComparer<Customer> implementation? 
IEnumerable<Customer> resultsC = listA.Where(a => !listB.Any(b => b.Id == a.Id)); 

// are the lists particularly large? perhaps try a hashset approach 
HashSet<int> customerIds = new HashSet<int>(listB.Select(b => b.Id).Distinct()); 
IEnumerable<Customer> resultsD = listA.Where(a => !customerIds.Contains(a.Id)); 

...

class CustomerComparer : IEqualityComparer<Customer> 
{ 
    public bool Equals(Customer x, Customer y) 
    { 
     return x.Id.Equals(y.Id); 
    } 

    public int GetHashCode(Customer obj) 
    { 
     return obj.Id.GetHashCode(); 
    } 
} 
+0

Merci pour vos commentaires ... De cette ligne: listA.Where (a =>! ListB.Any (b => b.Id == a.Id)) ;, comment puis-je obtenir une troisième liste "C" qui a ces objets clients de A non présents dans B? – Jimmy

+0

@Jimmy, 'Liste listeC = listeA.Where (a =>! ListeB.Any (b => b.Id == a.Id)). ToList();' –

+0

Merci Anthony Pegram! Cela fonctionne très bien pour moi J'ai utilisé: listA.Where (a =>! ListB.Any (b => b.Id == a.Id)); approche. – Jimmy

5

Si vous surchargent equals pour votre objet client, puis il suffit d'utiliser

A.Except(B); 
4

Développant Sauf, en fournissant votre propre égalité de sorte que vous n'avez pas besoin pour changer votre comportement d'égal à égal. Je suis arrivé ce d'ici:

http://www.codeproject.com/KB/dotnet/LINQ.aspx#distinct

List<Customer> customersA = new List<Customer> { new Customer { Id = 1, Name = "A" }, new Customer { Id = 2, Name = "B" } }; 
List<Customer> customersB = new List<Customer> { new Customer { Id = 1, Name = "A" }, new Customer { Id = 3, Name = "C" } }; 

var c = (from custA in customersA 
     select custA.Id).Distinct() 
      .Except((from custB in customersB 
      select custB.Id).Distinct()); 
+0

Dans ce cas, 'var c' serait' IEnumerable ', représentant une séquence des identifiants uniques, non appariés, de' customersA'. Pour obtenir les objets 'Customer', ce résultat devrait être utilisé à nouveau pour extraire les objets de' customersA'. –

Questions connexes