7

I'm trying to compare two lists with the Except method but it doesn't work correct:

List<Customer> PotentialSharedCustomer = new List<Customer>();
PotentialSharedCustomer.Add(new Customer { AccountId = Guid.Empty, AccountNumber = "01234", Name = "Hans Jürgen" });
PotentialSharedCustomer.Add(new Customer { AccountId = Guid.Empty, AccountNumber = "05465", Name = "Beate Müller" });
PotentialSharedCustomer.Add(new Customer { AccountId = Guid.Empty, AccountNumber = "15645", Name = "Sabine Meyer" });
PotentialSharedCustomer.Add(new Customer { AccountId = Guid.Empty, AccountNumber = "54654", Name = "Moritz Kummerfeld" });
PotentialSharedCustomer.Add(new Customer { AccountId = Guid.Empty, AccountNumber = "15647", Name = "Hanna Testname" });

List<Customer> ActualSharedCustomer = new List<Customer>();
ActualSharedCustomer.Add(new Customer { AccountId = Guid.Empty, AccountNumber = "01234", Name = "Hans Jürgen" });
ActualSharedCustomer.Add(new Customer { AccountId = Guid.Empty, AccountNumber = "05465", Name = "Beate Müller" });
ActualSharedCustomer.Add(new Customer { AccountId = Guid.Empty, AccountNumber = "15645", Name = "Sabine Meyer" });

PrepareCreateSharedCustomer(PotentialSharedCustomer, ActualSharedCustomer);

public void PrepareCreateSharedCustomer(List<Customer> potentialSharedCustomer, List<Customer> actualSharedCustomer)
{
    List<Customer> result = potentialSharedCustomer.Except(actualSharedCustomer).ToList<Customer>();
}

The result of the variable "result" should be all records of "PotentialSharedCustomers", there are not in the list "ActialSharedCustomer":

PotentialSharedCustomer.Add(new Customer { AccountId = Guid.Empty, AccountNumber = "54654", Name = "Moritz Kummerfeld" });
PotentialSharedCustomer.Add(new Customer { AccountId = Guid.Empty, AccountNumber = "15647", Name = "Hanna Testname" });

I thougt "Except" is the correct way to solve this, but I get the return of all items of "PotentialSharedCustomer"

Thx for help

Raidri
  • 17,258
  • 9
  • 62
  • 65
Patrik
  • 1,119
  • 5
  • 18
  • 37
  • 6
    Did you override `Equals` and `GetHashCode` in `Customer`? – tukaef Oct 15 '13 at 14:00
  • 2
    possible duplicate of [LINQ Except operator and object equality](http://stackoverflow.com/questions/693324/linq-except-operator-and-object-equality) – Konrad Morawski Oct 15 '13 at 14:01
  • 1
    How are you comparing equality between two instances of Customer? If you're not doing anything special then you will get the results of a reference equality comparison. I assume you need to provide an IEqualityComparer which determines equality based on the account number. – Matt Oct 15 '13 at 14:02

3 Answers3

9

One way without overriding Equals or writing a custom IEqualityComparer is to get a list of identifiers and then filter your list:

List<string> accountNumbers = 
    potentialSharedCustomer.Select(c => c.AccountNumber)
                           .Except(actualSharedCustomer.Select(c => c.AccountNumber));

List<Customer> result = potentialSharedCustomer.Where(c => accountNumbers.Contains(c.AccountNumber));

You could look at other data structures like HashSet to improve the lookup performance but if the size is small this may be sufficient.

D Stanley
  • 149,601
  • 11
  • 178
  • 240
2

Customer should implement IEquatable<Customer>, which means you must implement public bool Equals(Customer other) (that return true, if other is equal to this), and public int GetHashCode().

Check out the documentation for examples: http://msdn.microsoft.com/en-us/library/bb300779.aspx

There's also this other StackOverflow answer that exemplifies how to make a GetHashCode() implementation: https://stackoverflow.com/a/263416/62802.

Community
  • 1
  • 1
tmadsen
  • 941
  • 7
  • 14
1
var distinctCustomer = PotentialSharedCustomer
    .Select(p => p.AccountNumber)
    .Except(actualSharedCustomer.Select(q => q.AccountNumber))
    .ToList();
yanckst
  • 438
  • 4
  • 17
  • 1
    While this code snippet may solve the problem, it doesn't explain why or how it answers the question. Please [include an explanation for your code](//meta.stackexchange.com/q/114762/269535), as that really helps to improve the quality of your post. Remember that you are answering the question for readers in the future, and those people might not know the reasons for your code suggestion. **Flaggers / reviewers:** [For code-only answers such as this one, downvote, don't delete!](//meta.stackoverflow.com/a/260413/2747593) – Patrick Aug 25 '17 at 00:02