2

EntityFramework とLinqKitを使用して、SQL に変換される式ツリーを構築しています。また、仕様パターンを使用してクエリを整理します。

ほとんどすべてのドメイン オブジェクトで説明によるクエリを実行する必要がありますが、これらのクラスの一部では、プロパティは「名前」と呼ばれ、他のクラスでは「説明」などと呼ばれます。

したがって、最初は次のようにインターフェイスが定義されていました。

public interface IDescritible
{
    string Description { get; }
}

クラスに明示的に実装されたものを使用しようとしたときに問題が発生し、それに対して一般的なクエリを作成しました。

public class Foo : IDescritible
{
    public string Name { get; set; }

    string IDescritible.Description
    {
        get { return this.Name; }
    }
}

public class DescriptionMatch<T> : AbstractSpecification<T> 
    where T : IDescritible
{
    public string Query { get; set; }

    public DescriptionMatch(string query)
    {
        this.Query = query;
    }

    public override Expression<Func<T, bool>> IsSatisfiedBy()
    {
        return x => x.Description.Contains(Query);
    }
}

実行時に、EntityFramework はプロパティ get (メソッド呼び出し) を SQL 式に変換できません。

次に、次のようにクラスで Expression を定義しようとしました。

public interface IDescritible<T> where T: IDescritible<T>
{
    Expression<Func<T, string>> DescriptionExpression { get; }
}

public class Foo : IDescritible<Foo>
{
    public string Name { get; set; }

    public Expression<Func<Foo, string>> DescriptionExpression
    {
        get { return x => x.Name; }
    }
}

public class DescriptionMatch<T> : AbstractSpecification<T> where T : IDescritible<T>
{
    public string Query { get; set; }

    public DescriptionMatch(string query)
    {
        this.Query = query;
    }

    public override Expression<Func<T, bool>> IsSatisfiedBy()
    {
        Expression<Func<T, bool>> combinedExpression = x => x.DescriptionExpression.Invoke(x).Contains(this.Query);
        return combinedExpression.Expand();
    }
}

ただし、.Expand() を実行すると、例外がスローされます: タイプ 'System.Linq.Expressions.PropertyExpression' のオブジェクトをタイプ 'System.Linq.Expressions.LambdaExpression' にキャストできません。

次に、LinqKit はローカルで定義された式の展開のみをサポートし (この質問に記載されているように)、それらの問題を解決するために非公式のコードが記述されていることがわかりました (この質問の回答)。

しかし、LinqKit ライブラリを変更して、2 番目の質問で提案された解決策のいずれかを試すと、次のようにスローされ始めました: スコープ '' から参照されるタイプ 'Foo' の変数 'x' が定義されていません。

Foo のインスタンスをまだ持っていないことが原因でしょうか? ジェネリック型パラメーターのみを取得したため、ローカル変数で式を定義できません。クラスに何らかの形で「アタッチ」された静的式として定義する方法があるのではないでしょうか? しかし、それを一般的なクエリで使用することはできません。インターフェイスはありません...

インターフェイスの明示的な実装で定義された式を作成できるように、LinqKit を変更する方法はありますか? または、明示的に実装されたプロパティに対して一般的なクエリを作成する別の方法はありますか? または、他の解決策や検討すべきことはありますか?

そのためにLinqKitも仕様パターンも使用する必要はありませんが、EntityFrameworkは必須です。重要なのは、説明プロパティであるプロパティを「指摘」し、その上で一般的な式を作成することをサポートするインターフェース/その他の方法を持つことです。 .

前もって感謝します!

4

1 に答える 1