Linq的出现,使数据集的处理显得愈来愈简便。很多时候对于本地数据集的处理,脑海中的第一反应,即尝试使用Linq来实现。诸如DataTable的innerJoin以及leftJoin等操作,很多时候我们一接到类似的需求,立马便动手,诸如以下demo:

一、InnerJoin

 1             var qMyMx = from mxDr in _dtJgTcDetail.Rows.Cast<DataRow>().Where(drMx => id.Equals(drMx["TCID"].ToString()))
 2                         join item in _dtCashItem.Rows.Cast<DataRow>() on mxDr["SFXMID"].ToString() equals item["ID"].ToString()
 3                         select new
 4                         {
 5                             SFXMID = mxDr["SFXMID"].ToString(),
 6                             TCID = mxDr["TCID"].ToString(),
 7                             MC = item["MC"].ToString(),
 8                             NUM = mxDr["NUM"].ToString(),
 9                             DW = item["DW"].ToString(),
10                             GBBM = item["GBBM"].ToString(),
11                             ID = mxDr["ID"].ToString()
12                         };

View Code

上面的Demo便是一个典型的InnerJoin,通过_dtJgTcDetail的SFXMID列 同 _dtCashItem的ID列进行联查。我们就会感叹Linq让我们对数据源的筛选变的如此简单,但如果是联合主键的时候,我们又如何处理多条件的联查呢?接着一起看下面的Demo:

 1             var qMyMx = from mxDr in _dtJgTcDetail.Rows.Cast<DataRow>().Where(drMx => id.Equals(drMx["TCID"].ToString()))
 2                         join item in _dtCashItem.Rows.Cast<DataRow>() on new { XMID = mxDr ["TCID"].ToString(), JGLB = mxDr["JGBM"].ToString()} equals new { XMID = item["TCID"].ToString(), JGLB = item["JGLBBM"].ToString() }
 3                         select new
 4                         {
 5                             SFXMID = mxDr["SFXMID"].ToString(),
 6                             TCID = mxDr["TCID"].ToString(),
 7                             MC = item["MC"].ToString(),
 8                             NUM = mxDr["NUM"].ToString(),
 9                             DW = item["DW"].ToString(),
10                             GBBM = item["GBBM"].ToString(),
11                             ID = mxDr["ID"].ToString()
12                         };

View Code

这样我们就能像数据库那样在本地进行实现。

正当本小菜得意洋洋的千篇一律的使用着Linq,有一天,一个同事提出了这样的想法,如何封装一个动态的InnerJoin呢(能接收不同的联查条件)?这让本小菜一愣神,怎么才能实现动态查询条件的InnerJoin。正好最近小菜在学习咱们原子里大牛老赵的Expression系列,于是,我想既然是动态查询条件,能否把这部分抽出来交给开发者来动态实现呢?于是如果传入 Expression<Func<DataRow,DataRow,bool>> exp 类型的参数能否实现心中所想?立马尝试,如下Demo:

 1         public static IEnumerable<dynamic> InnerJoin(DataTable fstDt, DataTable ScdDt, Expression<Func<DataRow,DataRow,bool>> exp)
 2         {
 3             try
 4             {
 5                 var q = from dr1 in fstDt.Rows.Cast<DataRow>()
 6                         from dr2 in ScdDt.Rows.Cast<DataRow>()
 7                         where exp.Compile()(dr1, dr2)
 8                         select new { dr1, dr2 };
 9
10                 return q == null ? null : q.ToList();
11             }
12             catch { }
13             return null;
14         }

View Code

接着调用代码测试,如下

 1                     var qMyMx = ClsComUI.InnerJoin(_dtJgTcDetail.Rows.Cast<DataRow>().Where(drMx => id.Equals(drMx["TCID"].ToString())).CopyToDataTable(),
 2                                                     _frmFth._dtCashItem,
 3                         (mxDr, item) => mxDr["SFXMID"].ToString().Equals(item["ID"].ToString()));
 4
 5                     if (qMyMx.Count() > 0)
 6                     {
 7                         (gridControl2.DataSource as DataTable).Rows.Clear();
 8                         DataTable dtMxBind = gridControl2.DataSource as DataTable;
 9                         qMyMx.ToList().ForEach(myItem =>
10                         {
11                             DataRow drItem = dtMxBind.NewRow();
12                             drItem["SFXMID"] = myItem.dr1["SFXMID"].ToString();
13                             drItem["TCID"] = myItem.dr1["TCID"].ToString();
14                             drItem["MC"] = myItem.dr2["MC"].ToString();
15                             drItem["NUM"] = myItem.dr1["NUM"].ToString();
16                             drItem["DW"] = myItem.dr2["DW"].ToString();
17                             drItem["GBBM"] = myItem.dr2["GBBM"].ToString();
18                             drItem["ID"] = myItem.dr1["ID"].ToString();
19
20                             dtMxBind.Rows.Add(drItem);
21                         });
22
23                         //初始化明细的明细库缓存
24                         DoQueryJgMxk_MX(dtMxBind);
25                         gridView2_FocusedRowChanged(null, null);
26                     }
27                     else
28                     {
29                         (gridControl2.DataSource as DataTable).Rows.Clear();
30                     }

View Code

初步测试通过,汗,小菜只能实现封装到此部分,如果在多表联查只能进行重载扩展了。

另外调用此方法,

var qMyMx = ClsComUI.InnerJoin(_dtJgTcDetail.Rows.Cast<DataRow>().Where(drMx => id.Equals(drMx["TCID"].ToString())).CopyToDataTable(),
_frmFth._dtCashItem,
(mxDr, item) => mxDr["SFXMID"].ToString().Equals(item["ID"].ToString()));

传入的变量为(mxDr, item)

而输出的时候

drItem["SFXMID"] = myItem.dr1["SFXMID"].ToString();
drItem["TCID"] = myItem.dr1["TCID"].ToString();
drItem["MC"] = myItem.dr2["MC"].ToString();
drItem["NUM"] = myItem.dr1["NUM"].ToString();
drItem["DW"] = myItem.dr2["DW"].ToString();
drItem["GBBM"] = myItem.dr2["GBBM"].ToString();
drItem["ID"] = myItem.dr1["ID"].ToString();

只能使用公共方法内部定义的输出dr1和dr2。

小菜一直困扰如何解决,望各位大神告知小菜如何解决....在此,先感谢了。LeftJoin版本差不太多,直接附上代码:

二、LeftJoin版本

 1         public static IEnumerable<dynamic> LeftJoin(DataTable fstDt, DataTable ScdDt, Expression<Func<DataRow, DataRow, bool>> exp)
 2         {
 3             try
 4             {
 5                 var q = from dr1 in fstDt.Rows.Cast<DataRow>()
 6                         from dr2 in ScdDt.Rows.Cast<DataRow>().Where(needRows => exp.Compile()(dr1, needRows)).DefaultIfEmpty()
 7                         select new { dr1, dr2 };
 8
 9                 return q == null ? null : q.ToList();
10             }
11             catch { }
12             return null;
13
14             //var qRstXm = ClsComUI.LeftJoin(q.Where(drFil => drFil["TCBZ"].ToString().Equals("0")).CopyToDataTable(),
15             //                                _dtJgMxk,
16             //                                (drYz, drJg) => drYz["SFXMID"].ToString().Equals(drJg["XMID"].ToString()) && strJglb.Equals(drJg["JGLBBM"].ToString())
17             //    );
18
19             //var qRstTc = ClsComUI.LeftJoin(q.Where(drFil => drFil["TCBZ"].ToString().Equals("1")).CopyToDataTable(),
20             //                                _dtJgMxk,
21             //                                (drYz, drJg) => drYz["TCID"].ToString().Equals(drJg["TCID"].ToString()) && strJglb.Equals(drJg["JGLBBM"].ToString())
22             //    );
23         }

View Code

转载于:https://www.cnblogs.com/jchl/p/3776286.html

linq之InnerJoin和LeftJoin以及封装动态查询条件版本相关推荐

  1. 浅析Entity Framework Core2.0的日志记录与动态查询条件

    前言 Entity Framework Core 2.0更新也已经有一段时间了,园子里也有不少的文章.. 本文主要是浅析一下Entity Framework Core2.0的日志记录与动态查询条件 去 ...

  2. ibatis动态查询条件(转载待完善)

    ibatis动态查询条件(转载待完善) IBatis 动态查询条件 下面这个配置基本上包含了最复杂的功能:分页\搜索\排序\缓存\传值Hash表\返回hash表\动态sql <statement ...

  3. ibatis动态查询条件

    ibatis的调试相对困难,出错的时候主要依据是log4生成的log文件和出错提示,这方面要能比较熟练的看懂. 下面这个配置基本上包含了最复杂的功能:分页\搜索\排序\缓存\传值Hash表\返回has ...

  4. Vue动态查询条件-Vue动态查询规则-Vue多条件分组组合查询-递归组件(一):前端

    先看最终的效果: 最近项目上有一个需求,VUE前端要实现动态查询条件组件,后端就能够动态组装SQL. 要模仿人家Azure Devops的查询功能,我丢,Azure Devops是人家微软开发的个东西 ...

  5. Springboot中对jpa动态查询条件的封装

    jpa对于固定参数的条件查询比较简单,可以在Repository中直接用参数名来查询.但是对于不固定的参数查询就比较麻烦了,官方提供的是继承JpaSpecificationExecutor,然后自己拼 ...

  6. jpa 动态查询条件 数组_Spring data jpa 复杂动态查询方式总结

    一.Spring data jpa 简介 首先JPA是Java持久层API,由Sun公司开发, 希望整合ORM技术,实现天下归一.  诞生的缘由是为了整合第三方ORM框架,建立一种标准的方式,目前也是 ...

  7. java中动态查询条件,Java实现动态添加查询条件

    今天遇到一个问题,就是需要根据前端页面发送的条件查询数据库记录,但是前端发送的条件是不确定的.如果使用mybatis的xml方法可以使用if标签灵活的添加判断条件,但是现在我使用的就是单纯的sql. ...

  8. elk7.7.1【系列十六】java 封装 kql 查询条件

    src_ip.keyword : 192.168.31.1 and category.keyword : "其他僵尸网络通信"    =>    BoolQueryBuild ...

  9. sql不用拼接语句实现动态查询条件

    DECLARE @oFrom INT SET @oFrom = 2SELECT * FROM baseinfo WHERE 1 = 1 AND ((@oFrom = 0 and Type = 'Ord ...

最新文章

  1. python2 json大数据_大数据技术之python 操作json
  2. Windows下使用explorer批量下载文件
  3. python网上授课_python完整课程
  4. Boost库之asio io_service以及run、run_one、poll、poll_one区别
  5. 麦芒七怎么装鸿蒙,华为麦芒7怎么进行双清_清理缓存和恢复出厂设置的方法
  6. 不装oracle进行远程连接解决办法 .
  7. 学习响应式BootStrap来写融职教育网站,Bootsrtap第五天页脚
  8. Mybatis-plus 思维导图,让 Mybatis-plus 不再难懂
  9. c++ 经典代码_C语言经典100题(31)
  10. RGB与YUV格式简介
  11. php二进制保存到本地,C# 将二进制字符串保存到本地
  12. 接口监控_java应用监控之利用cat接口性能优化,每一次都是血的教训
  13. oracle日期大于3个月,用三个月时间做oracle实验,养成实验习惯
  14. ssis 数据转换_SSIS数据类型:高级编辑器的更改与数据转换的转换
  15. Eclipse启动时 弹出subversive connector discovery
  16. mysql关联子查询_MySQL 关联子查询
  17. html背景图片循环自动播放,CSS3 背景图循环播放
  18. 股票、基金、场内ETF基金下载数据代码例子
  19. 全球最最可爱的的10种著名小型犬
  20. 项目整体管理(6个过程:制定项目章程,制定项目管理计划,指导与管理项目工作,实施整体变更控制,结束项目或阶段)

热门文章

  1. 简单了解request与response
  2. pandas Timestamp的用法
  3. 正余弦定理解三角形习题
  4. oracle创建用户、表空间、临时表空间、分配权限步骤详解
  5. vs2013突然没有代码提示功能了。
  6. Linux 学习_在Linux下面安装eclipse
  7. [转]收录全部作品,《寂静岭套装》发售开始
  8. C# SortedDictionary以及SortedList的浅谈
  9. 你朋友圈里的广告是怎么做到合你胃口的?
  10. 洛谷—— P1605 迷宫