C# 根据用户选择在运行时构建动态谓词
我正在构建一个表单,以显示将根据WinForm应用程序中的用户条件进行筛选的列表, 假设我有一个通用列表C# 根据用户选择在运行时构建动态谓词,c#,dynamic,lambda,runtime,C#,Dynamic,Lambda,Runtime,我正在构建一个表单,以显示将根据WinForm应用程序中的用户条件进行筛选的列表, 假设我有一个通用列表IList和Order 具有一些属性,例如OrderId,CustomerName,CreationDate public Class Order { public string OrderId {get; set;} public string CustomerName {get; set;} public DateTime CreationDate {get; set;} } 此外
IList
和Order
具有一些属性,例如OrderId
,CustomerName
,CreationDate
public Class Order
{
public string OrderId {get; set;}
public string CustomerName {get; set;}
public DateTime CreationDate {get; set;}
}
此外,我在表单中添加了一些控件,以便用户可以筛选列表。一个文本框
用于订单ID
另一个用于客户名称
和两个日期时间选择器
用于创建日期
范围(从日期时间选择器到日期时间选择器)
我还将谓词变量定义为:
Func<Order, bool> predicate = null;
但我得到了这个错误:
Operator '&&' cannot be applied to operands of type 'System.Func<Order,bool>' and 'lambda expression'
运算符“&&”不能应用于“System.Func”和“lambda expression”类型的操作数
您的代码不起作用,因为您实际上并没有将&&
应用于谓词的结果,而是将其应用于谓词本身。即使你这样写:
predicate = t => predicate(t) && t.CustomerName == customer;
它可以编译,但最终会得到无限递归
为了简单起见,您可以使用纯Linq(将与任何IEnumerable
一起使用)简单地执行此操作:
predicate = t => predicate(t) && t.CustomerName == customer;
IEnumerable<Order> results = ... // all items
if (tbOrderId.Text != string.Empty)
{
string orderId;
results = results.Where(t => t.OrderId == orderId);
}
if (tbCustomerName.Text != string.Empty)
{
string orderId;
results = results.Where(t => t.CustomerName == customer);
}
ParameterExpression parameter = Expression.Parameter(typeof(DateTime));
Expression predicate = Expression.Constant(true);
if (tbOrderId.Text != string.Empty)
{
string orderId = tbOrderId.Text;
Expression prop = Expression.PropertyOrField(parameter, "OrderId");
Expression filter = Expression.Equal(prop, Expression.Constant(orderId));
predicate = Expression.AndAlso(predicate, filter);
}
if(tbCustomerName.Text != string.Empty)
{
string customer = tbCustomerName.Text;
Expression prop = Expression.PropertyOrField(parameter, "CustomerName");
Expression filter = Expression.Equal(prop, Expression.Constant(customer))
predicate = Expression.AndAlso(predicate, filter);
}
Expression lambda = Expression.Lambda(predicate, parameter);
return results.Where(lambda);