Why can't List (T) .Contains find matches in Entity Framework object lists?

I have two lists of Client objects created from the Entity Framework. I need to compare the two lists to see if there are differences between them, so naturally I wrote something like this:

private static List<Customer> originalList; public static bool TestForEQ(List<Customer> source, List<Customer> destination) { foreach(Customer cust in originalList) { if( !currentList.Contains(cust) ) { return false; } } public static void CheckData() { var ctx = new CustomersEntities(); if(originalList == null) { originalList = ctx.Customers.ToList<Customer>(); } else { bool equiv = testForEQ(originalList, ctx.Customers.ToList<Customer>()); originalList = ctx.Customers.ToList<Customer>() } } 

CheckData is called periodically from the stream.

So, when I first stepped over it before making any changes to the database between when the originalList and currentList were created, I was surprised to find that the two initial objects in the list were not - according to Contains () - the equivalent and that the above code returns false.

I checked that the basic properties of two objects (Id, name, etc.) are equivalent and that no pair of objects from any list is considered equivalent to Contains (), therefore ..

1) Can someone help me find out which property (s) of two apparently identical data objects causes Contains () to fail?

2) Does anyone know anything about the structure of an entity, which can lead to the fact that two generated objects will not be equivalent if they are obtained from an untouched data table at different times? Is there any kind of timestamp? Or are they considered links?

+4
source share
1 answer

Because by default, you check referential equality ... and that doesn't work.

To make sure you get the expected results, you can create your own IEqualityComparer<T> (by implementing IEqualityComparer<T> ) and provide this with Contains() .

For example, the following implementation will compare customers based on their Id:

 public class CustomerEqualityComparer : IEqualityComparer<Customer> { public bool Equals(Customer c1, Customer c2) { return c1.Id == c2.Id; } public int GetHashCode(Customer c) { return c.Id.GetHashCode(); } } 

Then you can call Contains with:

 if(!currentList.Contains(cust, new CustomerEqualityComparer()) return false; 
+4
source

All Articles