質問

私はサブセットと比較してサブセットを除くすべてを選択するかを決定したいという実体を持っています。

このような

だから、私の質問になります。

Products.Except(ProductsToRemove(), new ProductComparer())
それはいくつかのタスクを実行した後、

ProductsToRemove()方法はList<Product>を返します。だからの最も単純な形式で、それは上だ。

このようなProductComparer()クラスのルックスます:

public class ProductComparer : IEqualityComparer<Product>
{
    public bool Equals(Product a, Product b)
    {
        if (ReferenceEquals(a, b)) return true;

        if (ReferenceEquals(a, null) || ReferenceEquals(b, null))
            return false;

        return a.Id == b.Id;
    }

    public int GetHashCode(Product product)
    {
        if (ReferenceEquals(product, null)) return 0;
        var hashProductId = product.Id.GetHashCode();
        return hashProductId;
    }
}

しかし、私は継続的に次の例外を受け取ります:

  

認識していないエンティティへのLINQ   方法   「System.Linq.IQueryable1[UnitedOne.Data.Sql.Product] Except[Product](System.Linq.IQueryable1 [UnitedOne.Data.Sql.Product]、   System.Collections.Generic.IEnumerable1[UnitedOne.Data.Sql.Product], System.Collections.Generic.IEqualityComparer1 [UnitedOne.Data.Sql.Product]「)   方法、およびこの方法にすることはできません   店舗の表現に翻訳ます。

役に立ちましたか?

解決

エンティティへのLINQのは、実際にクエリを実行していない、それは、サーバー上で実行することを、TSQLに変換します。

の通訳のあなたのコードです

はカバーの下には、演算子と共通の機能がどのように動作するかの知識とどのようにそれらTSQLに関連して符号化されます。問題は、L2Eの開発者は、あなたがたIEqualityComparerを実装しているか正確には分からないということです。したがって、彼らはあなたがクラスA == Bクラスを言うとき、あなたは(たとえば)「どこPerson.FirstName == FirstNameおよびPerson.LastName ==姓」。

を意味することを理解することはできません

だから、L2Eインタプリタは、それが認識しない方法に当たったとき、それはこの例外をスローします。

あなたはこれを回避することができる2つの方法があります。まず、あなたの平等の要件が、それを満たすには、任意のカスタムメソッドに依存しないことをどこで()を開発します。換言すれば、インスタンスの特性の等価性のテストではなく、クラスに定義されている方法に等しい。

第二に、あなたは、クエリの実行をトリガして、メモリのあなたの比較を行うことができます。たとえばます:

var notThisItem = new Item{Id = "HurrDurr"};
var items = Db.Items.ToArray(); // Sql query executed here
var except = items.Except(notThisItem); // performed in memory

これは明らかに、ワイヤ全体でより多くのデータを持参し、より多くのメモリを大量になります。最初のオプションは、通常は最高です。

他のヒント

あなたは、Entity SQLへのカスタムExceptIEqualityComparerコールを変換しようとしている。

もちろん、あなたのクラスは、SQLに変換することはできません。

あなたは、クライアント上で実行することを強制するためにProducts.AsEnumerable().Except(ProductsToRemove(), new ProductComparer())を記述する必要があります。これは、サーバからの製品のすべてをダウンロードすることに注意してください。

<時間>

ところで、あなたのProductComparerクラスは、このように、シングルトンである必要があります:

public class ProductComparer : IEqualityComparer<Product> {
    private ProductComparer() { }
    public static ProductComparer Instance = new ProductComparer();

    ...
}

IEqualityComparer<T>のみローカルに実行することができ、それは、SQLコマンドに変換することができない、したがって、エラー

ライセンス: CC-BY-SA帰属
所属していません StackOverflow
scroll top