3

このようなラムダを作成したい

user => user.Address == address

コンパイルされていませんが、戻りたいですLambdaExpression

ラムダがこのように定数を取る場合

user => user.Age == 50

次に、この方法を使用できます

    public static LambdaExpression PropertyEqual(Type tEntityType, string propertyName, object value)
    {
        // entity => entity.PropName == const
        var itemParameter = Expression.Parameter(tEntityType, "entity");
        return Expression.Lambda
        (
            Expression.Equal
            (
                Expression.Property
                (
                    itemParameter,
                    propertyName
                ),
                Expression.Constant(value) // Tried to replace this with Expression.Parameter or Expression.Variable but no luck
            ),
            new[] { itemParameter }
        );
    }

addressこのメソッドに、ラムダ式のすぐ外側のスコープからの変数を受け入れるようにするにはどうすればよいですか?

var addressPropertyName = "Address";
var address = new Address() {...};
var q = Repo.GetQuery().Where(PropertyEqual(typeof(User), addressPropertyName, address))

編集:私の質問を明確にしてください:Expression最初のラムダを生成する権利をどのように構築しますか?

更新: EF は非スカラー変数をサポートしていないため、これは不可能です

ここでuser => user.AddressId == addressId提案されているように、ラムダをに変更します。既知のナビゲーション プロパティからFKを取得する方法だけが問題です。AddressIdPropertyInfoAddress

4

1 に答える 1

4

変数に対して動的にクロージャーを生成することはできません (変数の有効期間をそのコンテキスト外で延長することはできません)。これはコンパイラーのトリック (それを行うためにコードを書き換える) であるためです。

クロージャーは必要ないが、追加のパラメーターが必要な場合は、追加のパラメーターを式に追加できます。

あなたは出来る

Expression<Func<string>> myExpr = () => address;

これで、住所を囲む式ができました。これで、2 つの式を組み合わせるだけで済みます。

メソッドを次のように変更する必要があります。

public static LambdaExpression PropertyEqual<T>(Type tEntityType, string propertyName, Expression<Func<T>> getValue)
{
   // entity => entity.PropName == const
   var itemParameter = Expression.Parameter(tEntityType, "entity");
   return Expression.Lambda
   (
       Expression.Equal
       (
           Expression.Property
           (
               itemParameter,
               propertyName
           ),
           Expression.Invoke(getValue) // You could directly use getValue.Body instead of Expression.Invoke(getValue)
       ),
       new[] { itemParameter }
   );
}
于 2013-08-01T10:12:17.480 に答える