LINQ动态组合查询

简介:

    最近在项目中用到了LINQ,在界面上有许多组合查询条件,我是一个比较懒的人,呵呵,不想在数据查询层写许多方法。我自己尝试写了个ExpressionLINQ动态查询,目的是到达了,但是我在代码的初始表达式为null,每次组合AND前都要判断是否为空,为空则返回右边的表达式。今天在网上Google了一下,看到肖坤Linq动态查询与模糊查询(带源码示例)讲到的《dynamic linq queries / dynamic where clause (part 2) 》,中老外写的PredicateExtensions类。便用这个类修改了下自己的方案。不在是全表达式树动态生成了。今天特地写了一个基于NorthwindDemo拿来和大家分享:

效果贴图:

      界面是用Telerik控件做的(控件对于我们后台开发人员来说就是少调样式)。

代码:

 

复制代码
using  System;
using  System.Web.UI;
using  System.Linq.Expressions;
 
public   partial   class  _Default : System.Web.UI.Page
{
    
private  OrderController controller  =   new  OrderController();
    
protected   void  Page_Load( object  sender, EventArgs e)
    {
        
if  ( ! IsPostBack)
        {
            Bindgrid(
null );
        }
    } 
    
public   void  Bindgrid(Expression < Func < Orders,  bool >>  whereqQuery)
    {
        grid.DataSource 
=  controller.GetOrders( 1 15 , whereqQuery,
 
new  QueryableOrderEntry < Orders, 
string > (t  =>  t.CustomerID, OrderDirection.DESC)); //  分页数目应该用分页控件,
这里只是简单测试,所以偷个懒
        grid.DataBind();
    }
     
protected   void  btnSearch_Click( object  sender, ImageClickEventArgs e)
    {
        Expression
< Func < Orders,  bool >>  expression  =  PredicateExtensions.True < Orders > ();
        
if  ( ! string .IsNullOrEmpty(txtCustomerId.Text.Trim()))
        {
            
string  str  =  txtCustomerId.Text.Trim();
            expression 
=  expression.And(o  =>  o.CustomerID.Contains(str));
        }
        
if  ( ! string .IsNullOrEmpty(txtEmplyeeId.Text.Trim()))
        {
            
string  str  =  txtEmplyeeId.Text.Trim();
            expression 
=  expression.And(o  =>  o.EmployeeID.HasValue  &&  
                o.EmployeeID.Value.Equals(
int .Parse(str)));
        }
        
if  (txtOrderDateStart.SelectedDate.HasValue)
        {DateTime dt
= txtOrderDateStart.SelectedDate.Value;
            expression 
=  expression.And(o  =>  o.OrderDate.HasValue
 
&&  o.OrderDate.Value  >=  dt);
        }
 
        
if  (txtOrderDateEnd.SelectedDate.HasValue)
        {
            DateTime dt 
=  txtOrderDateEnd.SelectedDate.Value;
            expression 
=  expression.And(o  =>  o.OrderDate.HasValue
 
&&  o.OrderDate.Value  <= dt);
        }
        Bindgrid(expression); 
    }
}
复制代码

 

 

其中其实很简单,主要方法就两个,一个事表达式树组合,和数据绑定。数据绑定,有一个

Expression> where查询条件。

ControllerCode

  
复制代码
using  System;
using  System.Collections.Generic;
using  System.Linq;
using  System.Web;
using  System.Linq.Expressions;
using  System.Diagnostics; 
public   class  OrderController
{
    
protected  NorthwindDataContext DataContext
    {
        
get
        {
            NorthwindDataContext context 
=  
HttpContext.Current.Items[
" NorthwindDataContext " ]
 
as  NorthwindDataContext;
            
if  (context  ==   null )
            {
                context 
=   new  NorthwindDataContext();
                HttpContext.Current.Items[
" NorthwindDataContext " =  context;
            }
            
return  context;
        }
    }
     
public  List < Orders >  GetOrders < TKey > ( int  currentPage,
 
int  pagesize, Expression < Func < Orders,  bool >>  whereQuery, 
QueryableOrderEntry
< Orders, TKey >  orderQuery)
// 重点在这里的参数 
    {
        IQueryable
< Orders >  query  =  DataContext.Orders;
        
if  (whereQuery  !=   null )
        {
            query 
=  query.Where(whereQuery);
        }
        
if  (orderQuery  !=   null )
        {
            
if  (orderQuery.OrderDirection  ==  OrderDirection.ASC)
            {
               query
=  query.OrderBy(orderQuery.Expression);
            }
            
else
            {
                query 
=  query.OrderByDescending(orderQuery.Expression);
            }
        }
        Debug.WriteLine(DataContext.GetCommand(query.Skip((currentPage 
-   1 *  pagesize)
            .Take(pagesize)).CommandText);
        
return  query.Skip((currentPage  -   1 *  pagesize).Take(pagesize).ToList();
    }
 
    
public   void  Save()
    {
        DataContext.SubmitChanges();
    }
}
复制代码

 

我的排序辅助类:
  
复制代码
using  System;
using  System.Linq.Expressions;
    
public   class  QueryableOrderEntry < TSource, TKey >
    {
 
        
public  QueryableOrderEntry(Expression < Func < TSource, TKey >>  expression)
        {
            
this .Expression  =  expression;
            OrderDirection 
=  OrderDirection.ASC;
        }
 
        
public  QueryableOrderEntry(Expression < Func < TSource, TKey >>  expression, 
                  OrderDirection orderDirection)
        {
            
this .Expression  =  expression;
            OrderDirection 
=  orderDirection;
        }
        
public  Expression < Func < TSource, TKey >>  Expression
        {
            
get ;
            
set ;
        }
 
        
public  OrderDirection OrderDirection
        {
            
get ;
            
set ;
        }
    }
    
public   enum  OrderDirection
    {
        ASC, DESC
    }
复制代码

 

老外的PredicateExtensions类很简单,只是真的思路很优秀,看到代码我们都会恍然大悟,
但是估计我这鼠辈很难想到。
  
复制代码
public   static   class  PredicateExtensions
{
    
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 >>  expression1,
            Expression
< Func < T,  bool >>  expression2)
    {
        var invokedExpression 
=  Expression.Invoke(expression2, 
expression1.Parameters.Cast
< Expression > ());
 
        
return  Expression.Lambda < Func < T,  bool >> (Expression.Or(
expression1.Body, invokedExpression), 
           expression1.Parameters);
    }
 
    
public   static  Expression < Func < T,  bool >>  And < T > ( this  Expression < Func < T,  bool >>  expression1, 
            Expression
< Func < T,  bool >>  expression2)
    {
        var invokedExpression 
=  Expression.Invoke(expression2, 
expression1.Parameters.Cast
< Expression > ());
 
        
return  Expression.Lambda < Func < T,  bool >> (Expression.And(expression1.Body, 
          invokedExpression), expression1.Parameters);
    }
}
复制代码

 

上面贴图条件输出框中输出的sql我也截了一个图来供参考:

sql看不全:故在这里也贴一个:
  
复制代码
SELECT   TOP  ( 15 [ t0 ] . [ OrderID ] [ t0 ] . [ CustomerID ] [ t0 ] . [ EmployeeID ] [ t0 ] . [ OrderDate ] ,
 
[ t0 ] . [ RequiredDate ] [ t0 ] . [ ShippedDate ] [ t0 ] . [ ShipVia ] [ t0 ] . [ Freight ] [ t0 ] . [ ShipName ] ,
 
[ t0 ] . [ ShipAddress ] [ t0 ] . [ ShipCity ] [ t0 ] . [ ShipRegion ] [ t0 ] . [ ShipPostalCode ]
[ t0 ] . [ ShipCountry ] FROM   [ dbo ] . [ Orders ]   AS   [ t0 ]
WHERE  ( [ t0 ] . [ CustomerID ]   LIKE   @p0 AND  ( [ t0 ] . [ EmployeeID ]   IS   NOT   NULL AND  
((
[ t0 ] . [ EmployeeID ] =   @p1 AND  ( [ t0 ] . [ OrderDate ]   IS   NOT   NULL AND  
((
[ t0 ] . [ OrderDate ] >=   @p2 AND  ( [ t0 ] . [ OrderDate ]   IS   NOT   NULL AND  
((
[ t0 ] . [ OrderDate ] <=   @p3 ) ORDER   BY   [ t0 ] . [ CustomerID ]   DESC
复制代码

 

在这里说老外的思想优秀,该讲解一下,但是限于篇幅,还有时间凌晨1点了,故改到下回讲解。
附带:
本随笔代码下载


作者:破  狼 
出处:http://www.cnblogs.com/whitewolf/ 
本文版权归作者,欢迎转载,但未经作者同意必须保留此段声明,且在文章页面明显位置给出原文连接,否则保留追究法律责任的权利。该文章也同时发布在我的独立博客中-个人独立博客博客园--破狼51CTO--破狼。http://www.cnblogs.com/whitewolf/archive/2010/08/02/1790166.html

相关文章
无影云电脑使用感受
简单谈谈无影云电脑使用的感受
1068 1
无影云电脑使用感受
|
DataX 数据格式 Java
DataX插件编写指南
DataX 是阿里巴巴集团内被广泛使用的离线数据同步工具/平台,实现包括 MySQL、Oracle、HDFS、Hive、OceanBase、HBase、OTS、ODPS 等各种异构数据源之间高效的数据同步功能。DataX采用了框架 + 插件 的模式,目前已开源,代码托管在github。
13671 1
|
11月前
|
存储 数据管理 测试技术
提升软件测试效率的实用技巧与策略
在软件开发过程中,测试是一个至关重要的环节,它直接关系到产品质量和用户体验。本文将探讨几种实用的技巧和策略,帮助测试人员提升工作效率,确保软件质量。从测试自动化到持续集成,我们将一一解析这些方法如何优化测试流程。
|
11月前
|
安全 测试技术 项目管理
中级软件设计师考试(软考中级)计算机专业英语
一些常用的英语词汇和短语,可能在软考中级设计师考试中有所帮助。
301 0
|
弹性计算 小程序 Android开发
你信吗?有人用云电脑玩《黑神话:悟空》Mac党有福了
本教程详细介绍如何利用阿里云无影云电脑轻松畅玩《黑神话·悟空》游戏,无需下载游戏客户端,开机即可体验。首先需下载无影客户端并购买个人铂金款云电脑(14.9元首月)。随后输入WeGame版或Steam版镜像分享码并选择电竞模式进行配置。最后在云电脑内启动WeGame客户端,添加并更新游戏后即可开始游戏。请注意游戏本身需额外购买。游戏结束后记得关闭云电脑以避免额外收费。更多详情参见阿里云官方文档。
612 1
|
存储 安全 Java
全网最全、最细致的Java日志框架以及门面技术(一)。
对于一个应用程序来说日志记录是必不可少的一部分。线上问题追踪,基于日志的业务逻辑统计分析等都离不日志。java领域存在多种日志框架,目前常用的日志框架包括Log4j 1,Log4j 2,Commons Logging,Slf4j,Logback,Jul。
全网最全、最细致的Java日志框架以及门面技术(一)。
|
负载均衡 Dubbo Java
Dubbo入门,这一篇就够了(二)
Dubbo入门,这一篇就够了
2510 0
Dubbo入门,这一篇就够了(二)
|
SQL 弹性计算 运维
EDS 微服务治理
EDS 微服务治理
1075 0
EDS 微服务治理
|
缓存 监控 NoSQL
原来 8 张图,就能学废 Reactor 和 Proactor
常见的 Reactor 实现方案有三种。 第一种方案单 Reactor 单进程 / 线程, 第二种方案单 Reactor 多线程, 第三种方案多 Reactor 多进程 / 线程
原来 8 张图,就能学废 Reactor 和 Proactor
重装Win7时提示“缺少所需的CD/DVD驱动器设备驱动程序”
好多朋友都是这样,自己的电脑用的时间长了而又懒得经常去清理修复,或者因为偶尔中毒,系统运行不畅甚至崩溃。这几天每天都在网上找资料、下载资料,弄得自己的本本凌乱不堪,也懒得花时间去整理修复了,今天,终于彻底罢工不干了。
重装Win7时提示“缺少所需的CD/DVD驱动器设备驱动程序”