原文:Linq to Sql : 动态构造Expression进行动态查询

前一篇在介绍动态查询时,提到一个问题:如何根据用户的输入条件,动态构造这个过滤条件表达式呢?
Expression<Func<ProductExt, bool>> predicate t => t.ProductName.Contains("che") && t.UnitPrice >= 22;

理想情况下,我希望可以像下面这样来构造predicate,这样,我们就可以使用&、| 、&=、|=来任意拼接过滤条件了:

   1: Expression<Func<ProductExt, bool>> predicate = null;
   2: predicate &= (t => t.ProductName.Contains("che")) | (t => t.UnitPrice >= 22);

但是理想与现实之间,似乎总有不可逾越的鸿沟……

前面的代码中,我们总是要写一常串Expression<Func<T, bool>>,写得都有点儿烦了,我妄想自定义一个类型,这样就不用每次都写这么长了,然后再针对这个自定义类型再进行运算符重载……然后我发现,Expression<Delegate>是密封类型(sealed),不给重载,没办法,只好老老实实的写,运算符重载也泡汤了。

无奈之下,只好实现了下面的这种方式,勉强凑合用着:

   1: Expression<Func<ProductExt, bool>> predicate = null;
   2: predicate = predicate.AndAlso(p => p.CompanyName.Length > 2)
   3:      .OrElse((Products p) => p.ProductName.Contains("che"))
   4:      .AndAlso((Products p) => p.UnitPrice >= 22);

运算得到的结果如下:p => (((p.CompanyName.Length > 2) || p.ProductName.Contains("che")) && (p.UnitPrice >= 22))

有了这个OrElse和AndAlso扩展,我们就可以对Expression<Func<T, bool>>为所欲为了……

不过跟之前文章中提到的一样,这里有个限制:虽然我们的Expression中,第一个可以凡泛型参数可以传任意值(譬如传ProductExt或Products或其他的,可以不必要求是同一种类型),但条件中用到的对象属性(譬如CompanyName、ProductName、UnitPrice ),必须在T中存在同名属性。

2010-12-31更新:

更新了ParameterConverter类,之前对二元运算符的右侧和方法参数直接求值的,所以不能处理Expression中含有&& 和 || 等二元运算符、及方法参数中包含Expression参数(例如list.Contains(p.CompanyName))的情况;现在增加了参数访问计数,如果二元表达式&&和||、及方法的参数中不包含Expression参数,则进行求值,否则不求值。代码如下:

                                                                     }

最后,上代码:LinqToSqlExtension

博客园的文件貌似有缓存,删掉重新上传,总是覆盖不了,只好单独上传了 ParameterConverter.rar

最新文章

  1. tyvj1098 任务安排
  2. Android下Cocos2d创建HelloWorld工程
  3. 提高Axure设计效率的10条建议 (转)
  4. 20145304 Java第四周学习报告
  5. CDN技术分享
  6. Aspose.Word 操作word复杂表格 拆分单元格 复制行 插入行 文字颜色
  7. 再析在spring框架中解决多数据源的问题
  8. Python 安全类目推荐 (持续更新)
  9. Android上使用MP3格式录制声音
  10. Linker Special Section Types
  11. 【POJ1733】【带标记并查集】Parity game
  12. ImageMaigck不支持中文路径的问题
  13. Python 一些常用模块的安装
  14. python中type dtype astype 的用法
  15. 属性复制方法,当属性名字不一致时候可以传入匹配的Map
  16. ionic3 使用html2canvas将数据导出为图片,并下载本地
  17. 面试:C++实现访问者模式
  18. python模块安装注意事项
  19. Android MD5算法
  20. Oracle 修改用户名

热门文章

  1. OpenCV视频播放方法
  2. Ehcache详细解读(转)
  3. html 块状元素 行内元素 内联元素
  4. [SignalR]Groups操作
  5. 软测试综述——PV操作
  6. NSIS:应用软件自动升级功能的探索与实践
  7. Python基本语法[二],python入门到精通[四] (转)
  8. 由于抽签HT For Web ComboBox下拉框组件
  9. word插入图片显示不完整的解决的方法
  10. PHP MVC自己主动RBAC自己主动生成的访问路由