2009-06-18 9 views
14

Bonjour!EF Distinct (IEqualityComparer) Erreur

Étant donné:

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

Ceci compile, mais l'exécution je vais obtenir un Linq to Entity could not translate Comparer -Exception.
Des suggestions?

Répondre

29

Si vous fournissez vos propres comparaisons, vous devrez exécuter l'appel Distinct au format .NET. Pour vous assurer que le cas, utilisez AsEnumerable pour transformer IQueryable<T> en IEnumerable<T>:

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

Bien sûr, à ce moment-là, vous serez en tirant plus de données sur la base de données. Une autre solution consiste à regrouper les données au lieu:

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

que vous obtiendrez la première entité rencontrée à chaque ID (en supposant ma requête-fu ne me parvient pas). C'est essentiellement ce que fait Distinct de toute façon, mais tout est dans la base de données.

(Note aux futurs lecteurs: appeler First() plus de sens que FirstOrDefault(), mais apparemment cela ne fonctionne pas.)

+0

Est-il possible de faire ce pas dans le .NET couche? D'une certaine manière, dites à l'appel EF de le faire en SQL? –

+0

Voir mon édition - utiliser le groupage et vous obtiendrez le comportement désiré. Ce serait bien d'avoir "DistinctBy" dans le framework (et géré par EF etc) mais je pense que la version groupée fera ce que vous voulez. –

+0

Merci! Cela me semble très plausible, car vous faites le groupe sur un IQueryable . Je vais essayer ça plus tard! PS: Oui, vous avez la Distinct-Condition correcte :) –