基于Expression Lambda表达式树的通用复杂动态查询构建器——《摘要篇》

本系列将会写成一个长连载,所写内容居于本人开发的构架中部分开源模块。预设文章简要大纲如下

一、从构思说起 

  1.  
  2.  
  3.  

二、描述器的实现

  1.  
  2.  
  3.  

 三、表达式的组装

  1.  
  2.  
  3.  

四、拓展应用场景

  1.  
  2.  
  3.  

基于表达式树的通用查询构造器 常见的使用Linq Expression的做法这种代码众多,随便一搜就是, 但几乎都是单个条件的,单层级的,只能简单组装,组装成如:

Field_A =1 and Field_B =2 Or Field_C=3 
--或者 
Field_A =1 and (Field_B =2 Or Field_C=3)
  是否可以灵活的查询条件组合 &独立的分离式的描述式条件,描述与执行分离的 &适应任何DTO的通用方案呢。

我们先来考查一个最简单的Sql where 子句: Id=1 当中有三种节点,分别为字段名:id,比较符:=,查询值:1 通过观察,我们用Name来标识字段名,Op来标识比较符,Value来标识查询值,那么数据结构可以设计为 :

{ "Name" : "id", "Op" : "=", "Value" : 1 }
  再来考查具有两个条件的子句:
Id=1 and name="MyName"

 

比上一条多了逻辑符:“and”,

那么我们添加两个节点,用Predicates来描述查询条件,用Lg来标识逻辑串接,数据结构可以设计为

 [ 
     {
      "lg" : "",
      	"Predicates" : {"Name" : "id", "Op" : "=", "Value" : 1 }
     },
     {
        "lg":"and",
      	"Predicates": { "Name" : "Name", "Op" : "=", "Value" : "MyName"}
     } 
 ] 
 

以下两条子句都比较常用,也都属于简单的子句,再来看稍微复杂点儿的子句:

Id>1 and Id<10 and (Name="MyName" or Name="HisName")
 

比上一条多了一对分组括号: 添加节点filters来容纳逻辑组合,数据结构可以设计为:

{
    "lg": "", 
    "filters":
    [ 
        { 
            "lg": "", 
            "Predicates":[ { "lg": "", "Name": "id", "Op": ">", "Value": 1 } ]
         }, 
         { 
            "lg": "and", 
            "Predicates":[ { "lg": "", "Name": "id", "Op": "<", "Value": 10 } ] 
         },
         {
            "lg": "and",
            "Predicates":
            [
                {"lg": "","Name": "name",  "Op": "=", "Value": "MyName"},         
                {"lg": "or","Name": "name","Op": "=","Value": "HisName"}
            ]
        }
    ]
}
 
--更复杂一点的等等:
Id=1 
 and (
     (Name="MyName" or Name="HisName") or (Phone like"13899%" and Emil Like "%@xx.com")
 )
 

基于此,期望能够以简洁的方式:

Query.Where(QueryFilterBuilder.CreateFilterExpression<Entity>(conditionBlock));

实现如下复杂的查询组合的复杂查询构建器:

where 
    ( 
        (            
            (A.Field_A + A.Field_B) / A.Field_C=(2+3) % 2 or A.Field_A= A.Field_C
			or (A.Field_C > 2 and Len(A.Field_D) < 2)
        ) 
        and (A.Field_E Like"%xxooxx" or A.Field_F in (1,2,3))
    ) 
    and A.Field_G in (select B.Field_N From B where cast(B.Fieild_DatetimeString as Datetime) = A.FieldDatetime)
)

如上所示,几乎可以实现任意条件,任意逻辑的组合查询。

理想这么美好,那么现实如何去实现,我们设计一个用来描述条件的对象:ConditionBlock用来承载上述查询条件的数据结构,再设计一个条件分析构造器:QueryFilterBuilder,使用它来创建Expression表达式树以构造Lambda查询表达式,由于条件描述与表达式构造分离,条件描述的工作可以放在任何地方,比如浏览器,它可以只需要提供符合数据结构的Json数据即可。

  • 先看看总体代码:
  • http://github.com/ls0001/QueryFilter(别忘记随手点亮一颗小星星哦/^.^)
  • 欲了解更多,挖掘更多,敬待下期分解。
本文转载于网络 如有侵权请联系删除

相关文章

  • LeetCode周赛252场:时隔半年再来练习

    文章目录先BB再说题1.三除数2.你可以工作的最大周数3.足够苹果最小花园长度4.统计特殊子序列的数量先BB有一段时间没有做算法题了,从准备春招开始就没有再参加过LeetCode周赛两三年前是能做对两三道题,这些年过去了,还是这个水平甚至还退步了不少。 仿佛还能想起刚开始接触LeetCode的时候周赛还是用iPad在Java课上偷偷写还只能做对第一道签到题第二题都不一定能写上。 那时候参加的人比现在少的多 还是自己太菜了,感觉身边的同学和学弟学妹的水平都是AC34题了现在。附上公司休息室的工作环境细心的同学会发现这个位置太晒了我就换到了另一边 再说题https://leetcode-cn.com/contest/weekly-contest-252/ 1.三除数一个数除数肯定有1和本身第三个看看2到sqrt(x)有没有其他的classSolution{ public: boolisThree(intn){ for(inti=2;i<=sqrt(n);i++){ if(i==sqrt(n))returntrue; if(n%i==0)returnfalse; }returnfals

  • 顶级的和掠夺性的一样?美国管理学会学报和Espacios的词汇结构观点

    这项研究比较了MB(管理-商业研究)中两个极端的文章标题和摘要的词汇结构:AMJ(美国管理学会学报),其最受尊敬的期刊之一,Espacios,其揭示了拉丁美洲MB的结构性问题。结果显示,标题长度和摘要的可读性与多样性的中位数存在显著差异,由于AMJ标题长度更长,摘要更加多样化且可读性要求更高。原文题目:Top-tierandpredatoryalike?AlexicalstructureperspectivefromtheAcademyofManagementJournalandSpacious原文:ThisstudycomparesthelexicalstructureofarticlestitlesandabstractsoftwoextremesinMB(management-businessresearch):theAMJ(AcademyofManagementJournal),oneofitsmostreveredperiodicals,andEspacios,theonethatunveiledastructuralprobleminLatin-AmericanMB.Res

  • 字节跳动自研强一致在线 KV &表格存储实践 - 上篇

    背景互联网产品中存在很多种类的数据,不同种类的数据对于存储系统的一致性,可用性,扩展性的要求是不同的。比如,金融、账号相关的数据对一致性要求比较高,社交类数据例如点赞对可用性要求比较高。还有一些大规模元数据存储场景,例如对象存储的索引层数据,对一致性,扩展性和可用性要求都比较高,这就需要底层存储系统在能够保证数据强一致的同时,也具有良好的扩展性。在数据模型上,有些数据比如关系,KV模型足够用;有些数据比如钱包、账号可能又需要更丰富的数据模型,比如表格。分布式存储系统对数据分区一般有两种方式:Hash分区和Range分区。Hash分区对每条数据算一个哈希值,映射到一个逻辑分区上,然后通过另外一层映射将逻辑分区映射到具体的机器上,很多数据库中间件、缓存中间件都是这样做的。这种方式的优点是数据写入一般不会出现热点,缺点是原本连续的数据经过Hash后散落在不同的分区上变成了无序的,那么,如果需要扫描一个范围的数据,需要把所有的分区都扫描一遍。相比而言,Range分区对数据进行范围分区,连续的数据是存储在一起的,可以按需对相邻的分区进行合并,或者中间切一刀将一个分区一分为二。业界典型的系统像HB

  • MYSQL 修改表结构 gh-ost 到底强哪里 作者自己来talk

    PT工具在MYSQL中的使用其实已经好像有“半个世纪了”,其出名的原因主要是因为pt-osc,如果你不知道,那你真的用过MYSQL,其实还有另外两家FB-OST,GH-OST. 实际上PT-OSC虽然使用了这么多年,他也存在一些问题PT-OSC 1有些操作中,会引起高负载的写操作2在原表和新表切换的过程中更名,可能有失败的可能(虽然这样的情况不多,但可能存在)3要求多,主键(具有唯一性的),表有外键的时候需要添加参数,并且很可能还是有问题,可能会导致主从延迟,表中不建议由其他trigger,PTOSC使用的就是update,insert,deletetriggers来解决原表和新表之间的数据同步的问题。 4对于大表,主业务表,还是不敢再业务时间来做,也是要到非业务或低峰期,来做。虽然有这么多那么多的问题,但也是用了很多年。FB-OST没有研究但原理也是类似的。(FB-OST)GH-OST其实是这三者里面,原理不一样的,有点开脑洞,开发者是一个DBA,拥有15年的经验。 以下为开发者,在GITHUB大会上的自我介绍 在考虑上面两个工具的缺点后,我使用了binarylog,虽然也我这里面

  • linux:根据主进程查找子进程

    版权声明:本文为博主原创文章,遵循CC4.0BY-SA版权协议,转载请附上原文出处链接和本声明。本文链接:https://blog.csdn.net/10km/article/details/100603320如下是我的项目中创建的一个java系统服务在通过systemctlstatus显示的服务状态$systemctlstatusfacelog ●facelog.service-facelogservice Loaded:loaded(/etc/systemd/system/facelog.service;enabled;vendorpreset:enabled) Active:active(running)since六2019-09-0717:25:29CST;27minago Docs:https://gitee.com/l0km/facelog Process:894ExecStop=/home/gyd/workspace/facelog-delivery/facelogstop(code=exited,status=0/SUCCESS) MainPID:1088(facelo

  • 论DFT | 一文读懂 ScanDEF 相关的一切

    ScanDEF用于记录Scanchain的信息,以在不同的工具中传递,如ATPG工具跟P&R工具。目前常用的ScanDEF版本是5.5,其格式如下: ScanDEF由如下几部分组成(注:由于目前常用的是muxedscanstyle,以下叙述都是基于muxedscanstyle,关于LSSDscanstyle如有兴趣,可私聊。): numScanChains:表示ScanDEF中chain的数目;ScanDEF中chain的数目跟设计中实际scanchain的数目并不相同,ScanDEF中每条chain上的所有寄存器必须由同一个clock驱动,而且必须由同一个clockedge触发;如果在插scanchain的时候使能了mixclock或mixclockedge,则设计中一条实际scanchain上可能有多个clock驱动的寄存器,也可能有多个clockedge触发的寄存器,这样的chain在写到ScanDEF中时,会被拆分成多条scanDEFchain.ScanDEF并不包含设计中所有在scanchain上的寄存器,它只包含可以reorder或repartition的部分,不能

  • Linux常用命令速查-系统监控

    本文涉及:Linux中进程管理命令:ps、pstree、grep、vmstat、进程树及进程搜索,查看系统负载命令uptime,查看内存信息free命令,常用工具top命令,磁盘监控df、du命令◆进程管理◆查看进程 ps复制常用参数:-A列出所有的行程-u指定用户的进程-ef所有进程以及启动命令-aux显示所有包含其他使用者的行程查看进程树pstree复制 搜索进程ps-ef|grep线程名称复制◆查看系统负载◆[root@master1~]#uptime 21:50:25up225days,3:24,3user,loadaverage:1.26,2.05,2.23复制上述结果意义:当前时间21:50:25系统运行时间up225days,3:24当前在线用户3最近1分钟负载1.26、5分钟负载2.0515分钟系统的负载 ◆查看内存信息◆free复制常用参数:-b以字节为单位-m以MB为单位-g以GB为单位-h易读格式-o不显示-/+buffers/cache行-t显示RAM+swap的总和-sn刷新间隔为n秒-cn刷新n次后即退出查看具体线程的内存信息 [root@VM_0_5_c

  • ClickHouse 集群迁移,你确认会吗

    clickhouse迁移的方案有很多,但是因为迁移稳单相对较少,很多人望而却步,这里为大家介绍3种方案一insertselectfromremote详情相关文档https://clickhouse.com/docs/en/sql-reference/table-functions/remote/INSERTINTOtableSELECT*FROMremote('ip','db.table','user','password')where...复制亲测,迁移亿级别一下的数据强烈推荐,不需要关心其他信息但是该方案和clickhouse的写入性能相关,在去重的引擎的情况下性能相对较差,时间是ClickHouse普通MergeTree的好几倍方案:去重复目标集群可以尝试先使用MergeTree来接受数据,然后通过一些其他方案来改为去重表引擎大数据量但是有分区的表也可以尝试按照分区迁移拆分任务优点:简单方案缺点:数据量不宜过大二fetchpart详情clickhouse在目标集群配置auxiliary_zookee

  • java获取kafka consumer lag、endOffsets、beginningOffsets以及 KafkaConsumer总结

    一、java获取kafkaconsumerlag、endOffsets、beginningOffsets maven依赖: <dependency> <groupId>org.apache.kafka</groupId> <artifactId>kafka-clients</artifactId> <version>0.10.1.0</version> </dependency> 复制 kafka-clients版本需要0.10.1.0以上,因为调用了新增接口endOffsets,lag=logsize-offset,logsize通过consumer的endOffsets接口获得;offset通过consumer的committed接口获得; importjava.util.ArrayList; importjava.util.HashMap; importjava.util.List; importjava.util.Map; importjava.util.Properties;

  • chapter1

    播放器播放条斗鱼、Youtobe等 https://web-streaming.github.io/ppbar/ 使用 使用ppbar,需要导入ProgressBar类和ppbar的样式。 importProgressBarfrom'ppbar'; import'ppbar/dist/index.min.css'; constdiv=document.createElement('div'); constbar=newProgressBar(div,{ //参数 }) document.body.appendChild(div) ProgressBar构造函数接收两个参数,第一个它的容器,第二个是ppbar的参数。如果设置第一个参数会自动将ppbar的DOM元素添加到传入容器中。 当然希望手动添加ppbar的DOM元素,可以不传入第一个参数。 importProgressBarfrom'ppbar'; import'ppbar/dist/index.min.css'; constbar=newProgressBar(undefined,{ //参数 }) documen

  • 2-2、线性代数方程组的求解

    内容来自王晓华老师 这块内容有点硬核,先做了解,主要学习如何使用迭代解决问题的步骤   两种常用的迭代法求解方程组,分别是雅可比迭代法(Jacobi)和高斯—赛德尔迭代法(Gauss—Seidel)   完整的雅可比迭代算法 constdoublePRECISION=0.000000001; constintVEC_N=16;//实际方程组的个数n必须小于VEC_N voidjacobi_eqn(doublea[][VEC_N],doubleb[],intn,doublex[]) { doublext[VEC_N]; doublemax_diff=0.0; do { for(inti=0;i<n;i++) { doublesum=0.0; for(intk=0;k<n;k++) { if(i!=k)//对角线元素不计算 { sum+=a[i][k]*x[k]; } } xt[i]=(b[i]-sum)/a[i][i];//根据关系计算xi的新值 } max_diff=calc_max_diff(xt,x,n); for(intj=0;j<

  • 字符串去重并去掉最后一个符号

    b='11,22,11,'b=b.split(',')d=''forcinb:ifcnotind:d+=str(c)d+=','else:passd=d[:-1]print(d)复制

  • samba服务开启后依旧无法从windwos进入centos目录

    Redhat使用了SELinux来增强安全,关闭的办法为: 永久有效 修改/etc/selinux/config文件中的SELINUX=""为disabled,然后重启。 即时生效 setenforce0 附注:如果还是不行那么就把windows的防火墙关掉,启动服务之后再开启防火墙

  • SharePoint 根据列表项目的元属性按照条件筛选列表项目 Web 部件

    SharePoint根据列表项目的元属性按照条件筛选列表项目Web部件 效果截图:     将Web部件添加到列表页面上     删选Country栏目为Germany     筛选城市为Berlin     编辑Web部件,可以选择供筛选的栏目     Web部件下载地址:点击此处下载。     后来知道原来是国人写的。     参考下面的博文: http://www.cnblogs.com/jianyi0115/archive/2011/12/09/2282287.html http://www.cnblogs.com/jianyi0115/archive/2008/02/15/1070158.html http://www.cnblogs.com/dreamnan/archive/20

  • python 魔法方法,属性,迭代

    9.2构造方法 python中也属于自己的构造函数和析构函数, classfibs: def__init__(self): self.a=0 self.b=1 defnext(self): self.a,self.b=self.b,self.a+self.b returnself.a def__iter__(self): returnself fib=fibs() foriinfib: ifi>1000: printi break 复制 其中的__init__就是在类创建对象的时候自动调用的,而下面两个函数就是在迭代的时候自动调用的,这是python实现的语法。 类在继承时不显示调用父类的构造方法时,父类构造方法中声明的元素不会被继承 classBird: def__init__(self): self.hungry=True defeat(self): ifself.hungry: print'Ohhh.haha!' self.hungry=False else: print'I\'mfullThanks!' classSongBird(Bi

  • Network of Schools - tarjan缩点

    题目:https://vjudge.net/contest/388498#problem/G 题意:有向图。每个点能把当前信息传达到其指向的点。问题1:至少需要提供给多少个点信息才能让信息传遍所有点;问题2:至少需要补多少条有向边才能,给任意一个点信息能够传遍所有点。 题解: 问题1实际上是问缩点后的图里有多少个入度为0的点。因为非入度为0的点可以从其他点那获得信息,不需要向他提供信息。 问题2实际上是问,缩点后图里入度为0的点数量rd0,出度为0的点的数量cd0。求这两个值的最大值。要实现题目的需求,就是对于任意一点,可以到达所有点。由这个可以推出,任意一点,都可以被其他点到达。等价于,任意一点,其入度和出度都不为0。 新建一条边最佳情况下可以减少一个入度为0的点和一个出度为0的点。所以至少需要max(rd0,cd0)条边。 参考博客:https://blog.csdn.net/weixin_42868863/article/details/102847615   #include<iostream> #include<stdio.h> #inc

  • LeetCode 104. 二叉树的最大深度

    我的LeetCode:https://leetcode-cn.com/u/ituring/ 我的LeetCode刷题源码[GitHub]:https://github.com/izhoujie/Algorithmcii LeetCode104.二叉树的最大深度 题目 给定一个二叉树,找出其最大深度。 二叉树的深度为根节点到最远叶子节点的最长路径上的节点数。 说明: 叶子节点是指没有子节点的节点。 示例: 给定二叉树[3,9,20,null,null,15,7], 3 /\ 920 /\ 157 返回它的最大深度 3。 复制 来源:力扣(LeetCode) 链接:https://leetcode-cn.com/problems/maximum-depth-of-binary-tree 著作权归领扣网络所有。商业转载请联系官方授权,非商业转载请注明出处。 解题思路 思路1-递归计算最深的子树 思路解析:因为树的深度是以最底层的叶子节点计算的,所以递归计算左右子树,若不是叶子节点就将深度+1并递归处理,由于左右子树都在递归,所以要求两者的最大值; 步骤: 左右子树递归

  • akka cluster sharding source code 学习 (1/5) 替身模式

    为了使一个项目支持集群,自己学习使用了akkacluster并在项目中实施了,从此,生活就变得有些痛苦。再配上apache做反向代理和负载均衡,debug起来不要太酸爽。直到现在,我还对akkacluster输出的log不是很熟悉,目前网络上akkacluster的信息还比较少,想深入了解这东西的话,还是要自己读sourcecode。前几天,雪球那帮人说akka不推荐使用,有很多坑,这给我提了个醒,目前我对akka的理解是远远不够的,需要深入学习。   akkaclustersharding是akka的一个extension。12年左右,有人在googlegroup中开始讨论dedicatedactorforeachentity这个概念,经过很多讨论,最终由 PatrikNordwall实现,以experimental的形式加入到akkacontri库里。我本来不知道有这么一个东西,甚至想过自己实现一个这样玩意。我并没有为clustersharding做过benchmark,也不知道该怎么做,http://dcaoyuan.github.io/papers/rpi_

  • 【Qt开发】QDate类

    QDate为开发者提供日期的类,函数也很丰富 常用方法介绍  1.QDateaddDays(qint64ndays)const     当前日期添加n天,n可以为负 2.QDateaddMonths(intnmonths)const     当前日期添加n月,n可以为负 3.QDateaddYears(intnyears)const     当前日期添加n年,n可以为负 4.intday()const     返回所处月的天数(1到31) 5.intmonth()const     返回日期的月数 6.intyear()const     返回日期的年数 7.intdayOfWeek()const     返回周几(1到7),0表示日期无效 8.intdayOfYear()const  &n

  • 接口(三):

    1、接口不能用于创建实例,但接口可以声明引用类型变量,并且该引用类型变量必须引用到其实现类的对象。 2、接口的主要用途:   .2.1、定义变量,也可用于进行强制类型转换   .2.2、调用接口中定义的常量   .2.3、被其它类实现 3、一个类可以实现多个接口,也是为了弥补Java类单继承灵活性的不足,而进行的补充,类实现接口的语法格式: [修饰符]class类名extends父类implements接口1,接口2...{   类体部分 } 复制  4、实现接口与继承父类相似,一样可以获得所继承接口里的常量(成员变量)、方法(抽象方法、默认方法,不包括类方法),代码如下: interfaceInterfaceA{ inta=1; voidtestA(); defaultvoidtestB(){ System.out.println("接口InterfaceA中的默认方法testB()"); } staticvoidtestC(){ System.out.println("接口InterfaceA中的类方法testC()"); } } publ

  • Cleanmymac X空间透镜再升级

    什么是空间镜透,在CleanmymacX中具体干什么使得?你了解多少?没关系,不要紧,看这里,下面给大家分享一下这款好用软件下的实用功能-空间透镜。盘它! 首先,CleanmymacX是一款Mac清理软件,一键操作,即可让Mac运行达到最佳。而空间透镜可以帮助我们对文件夹和文件进行视觉大小比较,方便更加快速的清理。CleanMyMacX本次版本更新在空间镜透上面做了很大的优化。让用户能够拥有更加直观的感受,让那些隐藏内容无处遁形。它改善了界面插图和图标支持高对比度模式,改进了整个应用中的按钮设计,界面展示上得到了很大的完善,让界面的画面感更加直观;   图1:界面全新升级 通过空间镜透功能我们可以实现层层分级,将每个软件的缓存,残余都一一区分,让用户更加直观的看到占比内存。   图2:软件内存占比 其次,全新版本支持VoiceOver功能,可以实现语音播报功能,方便用户更加直观的从试听方面达到理想效果;   图3:VoiceOver语音功能 最后,CleanMyMacX目前已经支持Outlook附件扫描,对于Windows操作系统的残留内容也可以实现清理。

相关推荐

推荐阅读