大楼前pression树的string.Contains [英] Building Expression Tree for string.Contains
问题描述
我努力建立一个EX pression树,所以我可以做动态过滤的一些数据。
我想出了这一点,但它无法在 VAR的λ=
行
的foreach(在request.Where.Rules VAR规则)
{
VAR parameterEx pression =前pression.Parameter(typeof运算(字符串),rule.Field);
VAR左=前pression.Call(parameterEx pression的typeof(串).GetMethod(TOLOWER,Type.EmptyTypes));
无功权=前pression.Constant(rule.Data.ToLower());
VAR方法= typeof运算(字符串).GetMethod(包含,新的[] {typeof运算(字符串)});
VAR通话=前pression.Call(左,法,权);
VAR的λ=前pression.Lambda< Func键< T,布尔>>(打电话,parameterEx pression);
查询= query.Where(拉姆达);
}
该变种规则
有一个字段(如姓名),我想与 rule.Data $ c中的文字比较$ C>(例如汤姆)。因此,如果
T.Name.Contains(汤姆);
我希望查询包括备案,否则不能
该变种查询
的类型是的IQueryable< T>
修改:终于有这个code工作:
的foreach(在request.Where.Rules VAR规则)
{
变种参数=实施例pression.Parameter(typeof运算(T),×);
VAR属性=前pression.Property(参数rule.Field);
VAR值=前pression.Constant(rule.Data);
VAR类型= value.Type;
VAR containsmethod = type.GetMethod(包含,新的[] {typeof运算(字符串)});
VAR通话=前pression.Call(财产,containsmethod,价值);
VAR的λ=前pression.Lambda< Func键< T,布尔>>(打电话,参数);
查询= query.Where(拉姆达);
}
您是几乎没有,但你的参数e pression应该是类型 T
,不字符串
,你也缺少了前pression了越来越从类型属性 T
类似的名字。
你应该大致有这
VAL - >防爆pression.Constant(typeof运算(字符串),rule.Field)
参数 - >防爆pression.Parameter(typeof运算(T),P)
属性 - >防爆pression.Property(参数属性名)
包含 - >防爆pression.Call(财产,containsmethod,VAL)
等于true - >防爆pression.True或等于,类似的东西
我freehanding所有这一切,所以它很可能有所不同是有效的。由此产生的EX pression应该是这样的。
P => p.Name.Contains(VAL)
I'm struggling to build an expression tree so I can dynamically do filtering on some data.
I have come up with this, but it fails at the var lambda =
line
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);
}
The var rule
has a Field (ex "Name") which I want to compare with the text in rule.Data
(ex 'tom'). So if T.Name.Contains("tom");
I want the query to include the record, otherwise, not.
The var query
is of type IQueryable<T>
EDIT: Finally got it working with this code:
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);
}
You are almost there, but your parameter expression should be of type T
, not String
, you are also missing the expression that is getting the property from type T
like name.
What you should roughly have is this
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
I am freehanding all of that, so it's likely somewhat different to be valid. The resulting expression should be something like this
p => p.Name.Contains(val)
这篇关于大楼前pression树的string.Contains的文章就介绍到这了,希望我们推荐的答案对大家有所帮助,也希望大家多多支持IT屋!