我需要构建一个可配置的查询构建器,允许用户复合任意数量的可能条件。例如,假设我们有Customer
,Order
,OrderItem
和Product
的经典案例。用户希望能够对包含3个以上项目的所有订单绘制报告。或者也许订单只有一个项目。基本上应该是相同的查询,除了比较器会有所不同。
用户可能还希望了解客户居住在区号10024中的情况。或者该订单至少包含/最多/正好2项产品ID 14.每个条件显然都需要硬编码它自己的方法,但每个条件的基本签名将是:
private static Expression<Func<Order, bool>> SomePredicate(object someParameters)
到目前为止,这就是我所描述的最后一个条件:
private static Expression<Func<Order, bool>> CountProductItems(int productID, int count, Comparator comparator) {
Expression<Func<Order, int>> productOrderItems =
order => order.Items.Where(i => i.ProductID == productID)
.Sum(i => i.Quantity);
switch (comparator) {
case Comparator.Equals:
// return... uh... now what?
case Comparator.GreaterThan:
// you get the picture....
}
}
我只是错过了最后一个语法步骤:如何使用该表达式productOrderItems
并返回表达式等于/小于/大于/ etc的顺序。提供的值count
。
你是怎么做到的?
答案 0 :(得分:1)
使用Expression
:
Func
个对象
Func<Order, int> productOrderItems =
(Order o) => o.Items.Where(i => i.ProductID == productID)
.Sum(i => i.Quantity);
然后在switch
内,您可以在productOrderItems
之上撰写另一个Lambda表达式作为返回值。它将自动转换为Expression
,因为Expression
和Func
在技术上可以互换:
switch (comparator) {
case Comparator.Equals:
return (Order o) => productOrderItems(o) == count;
break;
// etc.
}
答案 1 :(得分:0)
我已成功使用了ScottGu的Dynamic LINQ Query。
在我们的例子中,我们需要在运行时定义Where子句,它就像魅力一样。
它还向here提供了附加信息。
有了这个,你可以做类似的事情:
var query = Northwind.Products.Where("CategoryID=2 And UnitPrice>3");