7

一部のデータを動的にフィルタリングできるように、式ツリーを作成するのに苦労しています。

私はこれを思いついたが、それはvar lambda =ラインで失敗する

foreach (var rule in request.Where.Rules)
{
    var parameterExpression = Expression.Parameter(typeof(string), rule.Field);
    var left = Expression.Call(parameterExpression, typeof(string).GetMethod("ToLower", Type.EmptyTypes));
    var right = Expression.Constant(rule.Data.ToLower());
    var method = typeof(string).GetMethod("Contains", new [] { typeof(string) });
    var call = Expression.Call(left, method, right);
    var lambda = Expression.Lambda<Func<T, bool>>(call, parameterExpression);
    query = query.Where(lambda);
}

varには、 (ex'tom')のruleテキストと比較したいフィールド(ex "Name")があります。rule.DataしたがってT.Name.Contains("tom");、クエリにレコードを含めたい場合は、そうでない場合は含めません。

varqueryはタイプですIQueryable<T>

編集:ついにこのコードで動作するようになりました:

foreach (var rule in request.Where.Rules)
{
    var parameter = Expression.Parameter(typeof(T), "x");
    var property = Expression.Property(parameter, rule.Field);
    var value = Expression.Constant(rule.Data);
    var type = value.Type; 
    var containsmethod = type.GetMethod("Contains", new[] { typeof(string) });
    var call = Expression.Call(property, containsmethod, value);
    var lambda = Expression.Lambda<Func<T, bool>>(call, parameter);
    query = query.Where(lambda);
}
4

2 に答える 2

2

もうすぐですが、パラメータ式はタイプTではなくタイプである必要があります。また、nameのようなStringタイプからプロパティを取得している式もありません。T

大まかに持っておくべきものはこれです

val -> Expression.Constant(typeof(string), rule.Field)
parameter -> Expression.Parameter(typeof(T), "p")
property -> Expression.Property(parameter, "PropertyName")
contains -> Expression.Call(property, containsmethod, val)
equals true -> Expression.True or equals, something like that

私はそのすべてをフリーハンドで行っているので、有効であるとは多少異なる可能性があります。結果の式は次のようになります

p => p.Name.Contains(val)
于 2013-01-30T22:09:59.793 に答える
0

クエリを作成する場合は、クエリを作成してから呼び出し、を渡すWhere必要があります。これを試して:lambdaWherelambda

Expression<Func<T, bool>> lambda = Expression.Lambda<Func<T, bool>>(call, parameter);
MethodCallExpression expression = Expression.Call(typeof(Queryable), "Where",
                                    new[] { typeof(T) }, query.Expression, lambda);
query = query.Provider.CreateQuery<T>(expression);

それ以外の

var result = Expression.IsTrue(call);
query = query.Provider.CreateQuery<T>(result);
于 2013-01-31T10:53:16.667 に答える