2009-06-18 4 views
14

おはようございます!考えるEF Distinct(IEqualityComparer)エラー

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

これはコンパイルされますが、実行時に、私はLinq to Entity could not translate Comparer -Exceptionを取得します。
提案がありますか?

答えて

29

あなた自身の比較を提供している場合は、.NETコードでDistinct呼び出しを実行する必要があります。それが起こることを確認するには、IEnumerable<T>IQueryable<T>をオンにするAsEnumerableを使用します。

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

その時点であなたは、データベースから渡ってより多くのデータを引っ張っされます。代替グループに代わりデータです:

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

あなたに各IDに遭遇した最初のエンティティを取得します(私のクエリ-FUが私を失敗していないと仮定した場合)。これは基本的にDistinctがやっていることですが、データベースにすべてあります。

(将来の読者への注意:First()を呼び出すとFirstOrDefault()より理にかなっているが、どうやらそれは動作しません。)

+0

ない.NETレイヤでこれを行うにはチャンスがありますか?何とかSQLでこれを行うEF呼び出しを教えてください? –

+0

私の編集使用のグループ分けを見ると、あなたは希望の動作を得るでしょう。フレームワークに「DistinctBy」を持っているといいです(そしてEFなどで処理されます)が、グループ化されたバージョンではあなたが望むことができると思います。 –

+0

ありがとう!これは、あなたがIQueryable でグループをやっているので、私にとって非常に納得のいくものです。私はこれを後で試してみよう! PS:はい、Distinct-Conditionが正しいことを確認しました:) –