Why does List(T).Contains fail to find matches on lists of Entity Framework objects?

I've got two lists of "Customer" objects, generated from Entity Framework. I need to compare the two lists to see if there are any 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 a Thread.

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

I have verified that the basic properties of the two objects (Id, name etc) are equivalent and that no pair of objects from either list are treated as equivalent by Contains(), so ..

1) Can anyone help me find out what property(ies) of two apparently identical data objects are causing Contains() to fail on?

2) Does anyone know of anything on entity framework which would cause two generated entities to not be equivalent if fetched from an untouched data table at different times? Is there a timestamp of some sort? Or are they treated as references?

Answers


Because, by default, you're checking reference equality...and that is failing.

To be sure you get the results you expect, you can create a custom comparer (by implementing IEqualityComparer<T>) and provide that to the Contains() method.

For example, the following implementation would 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 could call Contains with:

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

Need Your Help

TabBar in a View Based Application with a UINavigationBar

iphone uiview uinavigationbar tabbar

I am making a View Based Application for iPhone and I am trying to make a UIView with a TabBar and a NavigationBar. The TabBar needs three buttons which should switch between three different UIViews.

GridView not conforming to Relativelayout alignment

java android layout gridview relativelayout

I'd like to right align this gridview so that it's flush against the right side of the screen, but it seems to always immediately follow whichever textview I set it to the right of. Not only that, ...

About UNIX Resources Network

Original, collect and organize Developers related documents, information and materials, contains jQuery, Html, CSS, MySQL, .NET, ASP.NET, SQL, objective-c, iPhone, Ruby on Rails, C, SQL Server, Ruby, Arrays, Regex, ASP.NET MVC, WPF, XML, Ajax, DataBase, and so on.