如何在VS2008中的Language Integrated Query动态条件查询

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);
如果每个条件合并都这么写会很麻烦,幸好已经有人给写好的辅助类: http://www.albahari.com/expressions/
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>>类型的表达式的合并了。具体用法参看 http://www.albahari.com/expressions/或 http://forums.microsoft.com/MSDN/ShowPost.aspx?PostID=1745163&SiteID=1
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和第一个完全相同。

你可能感兴趣的:(sql,query,vs2008, ,动态条件查询)