2010-12-03 5 views
4

Ich habe zwei Listen von "Kunden" -Objekten, die von Entity Framework generiert wurden. Ich brauche die beiden Listen zu vergleichen, um zu sehen, ob es irgendwelche Unterschiede zwischen ihnen sind so natürlich, ich so etwas wie dies schrieb:Warum findet List (T) .Contains keine Übereinstimmungen in Listen von Entity Framework-Objekten?

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>() 
    } 
} 

Prüfdaten in regelmäßigen Abständen von einem Thread aufgerufen wird.

Also, als ich es zum ersten Mal durchging, bevor ich irgendwelche Änderungen an der Datenbank zwischen der Erstellung von originalList und currentList vorgenommen habe, war ich überrascht zu sehen, dass die beiden ursprünglichen Objekte in der Liste nicht waren -) - Äquivalent und dass der obige Code falsch zurückgegeben wurde.

ich überprüft haben, dass die grundlegenden Eigenschaften der beiden Objekte (Id, Name usw.) entsprechen und dass kein Paar von Objekten aus beiden Listen werden als gleichwertig Enthält() behandelt, so ..

1) Kann mir jemand helfen herauszufinden, welche Eigenschaft (en) von zwei scheinbar identischen Datenobjekten bewirken, dass Contains() fehlschlägt?

2) Kennt irgendjemand etwas über das Entity-Framework, das dazu führen würde, dass zwei generierte Entitäten nicht gleichwertig sind, wenn sie zu unterschiedlichen Zeiten aus einer unberührten Datentabelle geholt werden? Gibt es einen Zeitstempel? Oder werden sie als Referenzen behandelt?

Antwort

4

Weil Sie standardmäßig die Referenzgleichheit überprüfen ... und das fehlschlägt.

Um sicher zu gehen, dass Sie die erwarteten Ergebnisse erhalten, können Sie einen benutzerdefinierten Vergleicher erstellen (indem Sie IEqualityComparer<T> implementieren) und diesen an die Contains()-Methode senden.

Zum Beispiel die folgende Implementierung Kunden auf der Grundlage ihrer Id vergleichen würde:

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(); 
    } 
} 

Dann könnten Sie rufen mit Enthält:

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

+1 Der EF Code Generator überschreibt nicht 'GetHashCode 'und' Equals' für Sie, können Sie entweder einen 'IEqualityComparer ' implementieren oder neue Implementierungen von 'GetHashCode' und' Equals' in der 'partially' Klasse hinzufügen. –

+1

IMO, noch besser für Ad-hoc-Szenarien ist nur 'Any()' von LINQ zu verwenden. 'if (! currentList.Any (c => c.Id == cust.Id))', und platziere einfach deine Vorstellung von Gleichheit in Lambda. –

+0

@Matt Greer das Problem mit der Verwendung von .Any() wie das ist am Ende mit Ihrem "Konzept der Gleichheit" codiert über Ihre ganze App, anstatt an einem Ort. –

Verwandte Themen