具有嵌套属性的动态linq表达式树
我有一个列表,我必须过滤子属性。 filter运算符是动态的,我正在使用谓词构建器来组合多个filter/ lambdas。
为简单起见,假设我有两个这样的类:
public class FirstClass { public int Id { get; set; } public ICollection MyList { get; set; } } public class SecondClass { public int ReferenceId { get; set; } public int Value { get; set; } }
我的filter使用引用ID,运算符类型和值,这样伪代码就像这样:
"list of FirstClass".Where(param1 => param1.MyList.Single(param2 => param2.ReferenceId == "reference id").Value "operatorType" "value")
实际的filter类似于123 eq 456
,其中引用id为123,operatorType为“eq”,值为456。
如果运算符只是相等,那么以下工作正常:
Expression<Func> lambda = param1 => param1.MyList.Single(param2 => param2.ReferenceId == id).Value == value;
此外,仅使用动态表达式对FirstClass
进行过滤,就像魅力一样,例如过滤Id(我的ExpressionTypeDictionary是用于根据提供的operatorType
选择ExpressionType
的字典):
var parameter = Expression.Parameter(typeof(FirstClass), "param1"); Expression body = parameter; body = Expression.Property(body, "Id"); body = Expression.MakeBinary(ExpressionTypeDictionary[operatorType], body, value); var lambda = Expression.Lambda<Func>(body, new[] { parameter });
我能够得到以下内容进行编译,但是使用EF Core对实际数据执行filter会返回querySource的exception:
var parameter = Expression.Parameter(typeof(FirstClass), "param1"); Expression<Func> left = param1 => param1.MyClass.Single(param2 => param2.ReferenceId == id).Value; var body = Expression.MakeBinary( ExpressionTypeDictionary[operatorType], left.Body, Expression.Constant(value)); var lambda = Expression.Lambda<Func>(body, new[] { parameter }); ... theList.Where(lambda);
任何建议值得赞赏:)
我想而不是像这样表达
Expression> predicate = x => x.MyList.Single(y => y.ReferenceId == id).Value [operator] value;
你最好建立一个这样的表达式:
Expression> predicate = x => x.MyList.Any(y => y.ReferenceId == id && y.Value == value);
以下是如何做到这一点:
上述就是C#学习教程:具有嵌套属性的动态linq表达式树分享的全部内容,如果对大家有所用处且需要了解更多关于C#学习教程,希望大家多多关注—计算机技术网(www.ctvol.com)!
var innerParameter = Expression.Parameter(typeof(SecondClass), "y"); var innerPredicate = Expression.Lambda>( Expression.AndAlso( Expression.Equal(Expression.Property(innerParameter, "ReferenceId"), Expression.Constant(id)), Expression.MakeBinary(ExpressionTypeDictionary[operatorType], Expression.Property(innerParameter, "Value"), Expression.Constant(value))), innerParameter); var parameter = Expression.Parameter(typeof(FirstClass), "x"); var predicate = Expression.Lambda>( Expression.Call( typeof(Enumerable), "Any", new Type[] { typeof(SecondClass) }, Expression.Property(parameter, "MyList"), innerPredicate), parameter);
本文来自网络收集,不代表计算机技术网立场,如涉及侵权请联系管理员删除。
ctvol管理联系方式QQ:251552304
本文章地址:https://www.ctvol.com/cdevelopment/954262.html