2009-06-18 11 views
14

Dzień dobry!EF Distinct (IEqualityComparer) Błąd

Dane:

public class FooClass 
{ 
    public void FooMethod() 
    { 
     using (var myEntity = new MyEntity) 
     { 
      var result = myEntity.MyDomainEntity.Where(myDomainEntity => myDomainEntity.MySpecialID > default(int)).Distinct(new FooComparer); 
     } 
    } 

} 

public class FooComparer : IEqualityComparer<MyEntity.MyDomainEntity> 
{ 
    public bool Equals(MyEntity.MyDomainEntity x, MyEntity.MyDomainEntity y) 
    { 
     return x.MySpecialID == y.MySpecialID; 
    } 

    public int GetHashCode(MyEntity.MyDomainEntity obj) 
    { 
     return obj.MySpecialID.GetHashCode(); 
    } 
} 

Będzie to skompilować, ale na starcie będę uzyskać Linq to Entity could not translate Comparer -Exception.
Jakieś sugestie?

Odpowiedz

29

Jeśli przeprowadzasz własne porównania, musisz wykonać wywołanie Distinct w kodzie .NET. Aby upewnić się, że zdarza się, użyj AsEnumerable włączyć IQueryable<T> do IEnumerable<T>:

var result = myEntity.MyDomainEntity 
     .Where(myDomainEntity => myDomainEntity.MySpecialID > default(int)) 
     .AsEnumerable() 
     .Distinct(new FooComparer()); 

Oczywiście w tym momencie będziesz ciągnięcie więcej danych z całej bazy danych. Alternatywą jest pogrupowanie danych Zamiast:

var result = from entity in myEntity.MyDomainEntity 
      where entity.MySpecialID > 0 
      group entity by entity.MySpecialID into groups 
      select groups.FirstOrDefault(); 

który będzie Ci pierwszy podmiot z każdą napotkaną ID (zakładając, że moje zapytanie-fu nie jest mi braku). To w zasadzie to, co czyni Distinct, ale to wszystko w bazie danych.

(Uwaga dla przyszłych czytelników: wywołanie First() większy sens niż FirstOrDefault(), ale najwyraźniej to nie działa.)

+0

Czy jest jakaś szansa, aby to zrobić nie w NET-Layer? W jakiś sposób powiedzieć wezwanie EF, aby zrobić to w SQL? –

+0

Zobacz moją edycję - użyj grupowania, a uzyskasz pożądane zachowanie. Byłoby miło mieć "DistinctBy" w strukturze (i obsługiwane przez EF itp.), Ale myślę, że zgrupowana wersja zrobi to, co chcesz. –

+0

Dziękujemy! Wydaje mi się to bardzo prawdopodobne, ponieważ robisz grupę na IQueryable . Spróbuję tego później! PS: Tak, masz prawidłowy stan Distinct) –