2010-09-08 1 views
6

Я 2 список коллекции в моей C# app..A и B.Использование Linq не равна

Обе коллекции имеют объект клиента, который имеет идентификатор и имя attributes.Typically, А имеет больше элементов, чем В.

Использование Linq, я хочу вернуть только тех клиентов, Id которых находится в A, но не в B.

Как это сделать?

+0

Что вы имеете в виду, «присоединиться на не равно условию»? –

+0

может у вашего вопроса немного конкретнее? – FosterZ

ответ

18

Существует несколько подходов. Самый чистый подход состоит в том, чтобы использовать метод расширения Except, если у вас есть override Equals и GetHashCode. Если вы этого не сделали, есть и другие варианты.

// 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

Спасибо за комментарии ур ... Из этой строки: listA.Where (a =>! ListB.Any (b => b.Id == a.Id)) ;, как мне получить третий список «C» который имеет те объекты клиента от A, не присутствующих в B? – Jimmy

+0

@Jimmy, 'Список listC = listA.Where (a =>! ListB.Any (b => b.Id == a.Id)). ToList();' –

+0

Спасибо Anthony Pegram! Это отлично работает для меня Я использовал: listA.Where (a =>! ListB.Any (b => b.Id == a.Id)); подход. – Jimmy

5

Если переопределить Equals для объекта клиента, а затем просто использовать

A.Except(B); 
4

Расширяя Кроме этого, обеспечивая собственное равенство, так что вам не нужно для изменения вашего поведения Equals. Я получил это отсюда:

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

В этом случае 'var c' будет' IEnumerable ', представляя последовательность уникальных непревзойденных идентификаторов из' customersA'. Чтобы получить объекты 'Customer', этот результат нужно будет использовать снова для извлечения объектов из' customersA'. –

Смежные вопросы