1

我正在构建一个表单来显示一个列表,该列表将根据我的 WinForm 应用程序中的用户条件进行过滤,假设我有一个通用列表IList<Order>Order 具有一些属性,例如OrderId, CustomerName, CreationDate,...

public Class Order
{
 public string OrderId {get; set;}
 public string CustomerName {get; set;}
 public DateTime CreationDate {get; set;}
}

另外,我在表单中放置了一些控件,以便用户可以过滤列表。一个TextBox代表OrderId另一个CustomerName,两个DateTimePickers代表CreationDateRange(FromDateTimePicker,ToDateTimePicker)。

我也将谓词变量定义为:

Func<Order, bool> predicate = null; 

predicate现在我如何根据用户输入值构建我的?

我试图写这段代码:

if (tbOrderId.Text != string.Empty)
{
   string orderId;
   predicate = t=>t.OrderId == orderId;
}
if(tbCustomerName.Text != string.Empty)
{
   string customer = tbCustomerName.Text;
   if(predicate!=null)
      predicate = predicate && (t=>t.CustomerName == customer);
   else
      predicate = (t=>t.CustomerName == customer);
}
....

但我收到此错误:

Operator '&&' cannot be applied to operands of type 'System.Func<Order,bool>' and 'lambda expression'
4

1 回答 1

2

您的代码不起作用,因为您实际上并未将 应用于&&谓词的结果,而是将其应用于谓词本身。即使你要这样写:

predicate = t => predicate(t) && t.CustomerName == customer;

它会编译,但你最终会得到一个无限递归。

为简单起见,您可以简单地使用纯 Linq 执行此操作(适用于 any IEnumerable<T>):

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);
}

或者这个 using 表达式(适用于IQueryable<T>):

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);
于 2013-06-10T08:19:45.600 回答