技术开发 频道

Linq动态条件查询


【IT168技术文档】

  1,构造表达式树
private Expression<Func<Blog, bool>> getCondition() { Expression<Func<Blog, bool>> expression = blog => true; if (!String.IsNullOrEmpty(Request["BlogClassID"])) { int blogClassID; if (Int32.TryParse(Request["BlogClassID"], out blogClassID)) { Expression<Func<Blog, bool>> e2 = blog => blog.BlogClass == null; var invokedExpr = Expression.Invoke(e, expression.Parameters.Cast<Expression>()); expression = Expression.Lambda<Func<Blog, bool>>(Expression.And(expression.Body, invokedExpr), expression.Parameters); } } return expression; }
  主查询是这个样子:
var result = new DongBlogDataContext().Blogs.Where(getCondition());
  因为根据SQL追踪,生成SQL类似:
SELECT [t0].[BlogID], [t0].[ChannelID], [t0].[BlogClassID], [t0].[Title], [t0].[Content], [t0].[Tag], [t0].[CreateDateTime] FROM [dbo].[Blog] AS [t0] WHERE [t0].[BlogClassID] IS NULL
  这种方法是实质是合并Lamba表达式,也就是这三句:
Expression<Func<Blog, bool>> e = blog => blog.BlogClass == null; var invokedExpr = Expression.Invoke(e, expression.Parameters.Cast<Expression>()); expression = Expression.Lambda<Func<Blog, bool>>(Expression.And(expression.Body, invokedExpr), expression.Parameters);

  如果每个条件合并都这么写会很麻烦,幸好已经有人给写好的辅助类:
using System; using System.Linq; using System.Linq.Expressions; using System.Collections.Generic; public static class PredicateBuilder { public static Expression<Func<T, bool>> True<T> () { return f => true; } public static Expression<Func<T, bool>> False<T> () { return f => false; } public static Expression<Func<T, bool>> Or<T> (this Expression<Func<T, bool>> expr1, Expression<Func<T, bool>> expr2) { var invokedExpr = Expression.Invoke (expr2, expr1.Parameters.Cast<Expression> ()); return Expression.Lambda<Func<T, bool>> (Expression.Or (expr1.Body, invokedExpr), expr1.Parameters); } public static Expression<Func<T, bool>> And<T> (this Expression<Func<T, bool>> expr1, Expression<Func<T, bool>> expr2) { var invokedExpr = Expression.Invoke (expr2, expr1.Parameters.Cast<Expression> ()); return Expression.Lambda<Func<T, bool>> (Expression.And (expr1.Body, invokedExpr), expr1.Parameters); } }
  这个类可以用于Expression<Func<T, bool>>类型的表达式的合并了。
  2,构造Query
  同第一种查询更好的写法:
private IQueryable<Blog> getQuery() { IQueryable<Blog> query = new DongBlogDataContext().Blogs; if (!String.IsNullOrEmpty(Request["BlogClassID"])) { int blogClassID; if (Int32.TryParse(Request["BlogClassID"], out blogClassID)) query = query.Where<Blog>(blog => blog.BlogClass == null); } return query.OrderByDescending(blog => blog.CreateDateTime); }
 主查询
var result = getQuery();
  生成的SQL和第一个完全相同.
0
相关文章