linq之InnerJoin和LeftJoin以及封装动态查询条件版本
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以及封装动态查询条件版本相关推荐
- 浅析Entity Framework Core2.0的日志记录与动态查询条件
前言 Entity Framework Core 2.0更新也已经有一段时间了,园子里也有不少的文章.. 本文主要是浅析一下Entity Framework Core2.0的日志记录与动态查询条件 去 ...
- ibatis动态查询条件(转载待完善)
ibatis动态查询条件(转载待完善) IBatis 动态查询条件 下面这个配置基本上包含了最复杂的功能:分页\搜索\排序\缓存\传值Hash表\返回hash表\动态sql <statement ...
- ibatis动态查询条件
ibatis的调试相对困难,出错的时候主要依据是log4生成的log文件和出错提示,这方面要能比较熟练的看懂. 下面这个配置基本上包含了最复杂的功能:分页\搜索\排序\缓存\传值Hash表\返回has ...
- Vue动态查询条件-Vue动态查询规则-Vue多条件分组组合查询-递归组件(一):前端
先看最终的效果: 最近项目上有一个需求,VUE前端要实现动态查询条件组件,后端就能够动态组装SQL. 要模仿人家Azure Devops的查询功能,我丢,Azure Devops是人家微软开发的个东西 ...
- Springboot中对jpa动态查询条件的封装
jpa对于固定参数的条件查询比较简单,可以在Repository中直接用参数名来查询.但是对于不固定的参数查询就比较麻烦了,官方提供的是继承JpaSpecificationExecutor,然后自己拼 ...
- jpa 动态查询条件 数组_Spring data jpa 复杂动态查询方式总结
一.Spring data jpa 简介 首先JPA是Java持久层API,由Sun公司开发, 希望整合ORM技术,实现天下归一. 诞生的缘由是为了整合第三方ORM框架,建立一种标准的方式,目前也是 ...
- java中动态查询条件,Java实现动态添加查询条件
今天遇到一个问题,就是需要根据前端页面发送的条件查询数据库记录,但是前端发送的条件是不确定的.如果使用mybatis的xml方法可以使用if标签灵活的添加判断条件,但是现在我使用的就是单纯的sql. ...
- elk7.7.1【系列十六】java 封装 kql 查询条件
src_ip.keyword : 192.168.31.1 and category.keyword : "其他僵尸网络通信" => BoolQueryBuild ...
- sql不用拼接语句实现动态查询条件
DECLARE @oFrom INT SET @oFrom = 2SELECT * FROM baseinfo WHERE 1 = 1 AND ((@oFrom = 0 and Type = 'Ord ...
最新文章
- python2 json大数据_大数据技术之python 操作json
- Windows下使用explorer批量下载文件
- python网上授课_python完整课程
- Boost库之asio io_service以及run、run_one、poll、poll_one区别
- 麦芒七怎么装鸿蒙,华为麦芒7怎么进行双清_清理缓存和恢复出厂设置的方法
- 不装oracle进行远程连接解决办法 .
- 学习响应式BootStrap来写融职教育网站,Bootsrtap第五天页脚
- Mybatis-plus 思维导图,让 Mybatis-plus 不再难懂
- c++ 经典代码_C语言经典100题(31)
- RGB与YUV格式简介
- php二进制保存到本地,C# 将二进制字符串保存到本地
- 接口监控_java应用监控之利用cat接口性能优化,每一次都是血的教训
- oracle日期大于3个月,用三个月时间做oracle实验,养成实验习惯
- ssis 数据转换_SSIS数据类型:高级编辑器的更改与数据转换的转换
- Eclipse启动时 弹出subversive connector discovery
- mysql关联子查询_MySQL 关联子查询
- html背景图片循环自动播放,CSS3 背景图循环播放
- 股票、基金、场内ETF基金下载数据代码例子
- 全球最最可爱的的10种著名小型犬
- 项目整体管理(6个过程:制定项目章程,制定项目管理计划,指导与管理项目工作,实施整体变更控制,结束项目或阶段)