摘要:[原文作者]:Jonathan Aneja [原文链接]:Implementing Dynamic Searching Using LINQ   在数据绑定应用程序中,一个比较常见的需求是:在程序运行时,用户能够使用任何字段的组合,动态构造条件进行查询。例如,在以下程序的查询功能中,用户可以任意组合多个列上定义的条件,并查询出符合条件的所有记录: 就像上图一样,通过各种数据源绑定,LINQ可以写出很强大的查询语句,例如,我们可以使用以下语句来查找指定的装运时间范围内,送到指定国家的所有订单: Dim query = From order In db.Orders _                       Where order.ShipCountry = txtCountry.Text _                       And order.ShippedDate >= dtpStartDate.Value _                       And order.ShippedDate <= dtpEndDate.Value   这很容易在编译时实现,但如果我们需要查询的是订单时间范围而不是装运时间范围呢?这种情况我们需要编写一个使用 order.OrderDate的查询。在运行时,动态生成一条这样的SQL语句不是一件难事,但如果用 LINQ应该怎么做呢? LINQ需要我们在编译时指定条件才能构造查询吗? 很幸运,答案是不,通过表达式树 API(Expression Tree API) 和表达式编译器(Expression Compiler),LINQ 支持在运行时构造动态查询. 在 Visual Studio 2008中,任何有效的VB表达式可表示为一个表达式树(Expression Tree)。 我们要做的是创建一个Expression Tree来表示该用户的条件,然后将它传递给LINQ to SQL[注①]来转换成SQL。 因此,上面 的Where子句可以写成这样: Dim p = Expression.Parameter(GetType(Order),"") Dim order = GetType(Order).GetProperty("ShipCountry") Dim expr = Expression.Equal(Expression.PropertyOrField(p,order.Name),Expression.Constant("Germany")) Dim predicate = Expression.Lambda(Of Func(Of Order,Boolean))(expr,New ParameterExpression() {p})   到目前为止,我们只完成了其中1/3的Where子句,为了动态构造一个Where子句而去写12行代码显得太啰嗦了!我会去写一个CreateCondition 的扩展方法,这个方法可以让我构造出Expression tree,而只需要用一行简单的代码就行了,参见: Dim condition1 = db.Orders.CreateCondition("ShipCountry",Compare.Equal,"Germany")   对于ShippedDate的日期查询条件,我们可以使用下面的startDate 和endDate: Dim startDate?= #1/1/1997# Dim endDate?= #1/31/1997#   Dim condition2 = db.Orders.CreateCondition("ShippedDate",Compare.GreaterThanOrEqual,startDate) Dim condition3 = db.Orders.CreateCondition("ShippedDate",Compare.LessThanOrEqual,endDate)   (注: 在Visual Studio 目录有一个叫DynamicQuery的项目,里面有更详细的应用). 注意到我们为第一个条件传入一个字符串”Germany”,后两个传入了可空类型的日期;因为CreateCondition是一个泛型方法,可以根据传入的参数推断出具体类型.我们现在需要把这几个条件集合成一个条件. Dim c = Condition.Combine(condition1,Compare.And,condition2,condition3) 或者可以利用操作符重载写成这样(和上面的效果一样): Dim c = condition1 And condition2 And condition3 好了,我们已经构造好了查询条件,让我们筛选出所需数据吧. 'Filter out all......[阅读全文]