【发布时间】:2017-03-14 18:50:06
【问题描述】:
我有一个必须过滤子属性的列表。过滤器运算符是动态的,我使用谓词构建器来组合多个过滤器/lambda。
为简单起见,假设我有两个这样的类:
public class FirstClass
{
public int Id { get; set; }
public ICollection<SecondClass> MyList { get; set; }
}
public class SecondClass
{
public int ReferenceId { get; set; }
public int Value { get; set; }
}
我的过滤器使用一个引用 id、一个操作符类型和一个值,这样一个伪代码会是这样的:
"list of FirstClass".Where(param1 =>
param1.MyList.Single(param2 =>
param2.ReferenceId == "reference id").Value "operatorType" "value")
实际的过滤器类似于123 eq 456,其中引用id 是123,operatorType 是“eq”,值是456。
如果运算符只是相等,那么以下工作就可以了:
Expression<Func<FirstClass, bool>> 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<FirstClass, bool>>(body, new[] { parameter });
我能够编译以下内容,但使用 EF Core 对真实数据执行过滤器会返回 querySource 异常:
var parameter = Expression.Parameter(typeof(FirstClass), "param1");
Expression<Func<FirstClass, int>> 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<FirstClass, bool>>(body, new[] { parameter });
...
theList.Where(lambda);
任何建议表示赞赏:)
【问题讨论】:
-
您可以使用 Gridify 库。 github.com/alirezanet/gridify
标签: c# entity-framework linq linq-expressions expressionbuilder