【声明】
写作不易,转载请注明出处(http://www.cnblogs.com/wiseant/p/3988592.html)。
 
【系列文章】
通用查询实现方案(可用于DDD)[附源码] -- 代码解读
 
【前言】
在上一篇博文中,我向大家简单介绍了Xant.Querier通用查询,并分享了项目源码。这一篇继续给大家分享我的设计思路,也为了日后自己翻看。
 
【如何表示最基本的条件】

最基本的查询条件可以描述为{字段}={值},运算结果为布尔值。比较运算符不一定是等于,可以是包含、大于、小于等于,那么可以将一个条件描述为这样的表达式,该表达式计算结果为布尔值:

{字段}.比较运算({值})
OK,我们已经完成了第一步,可以表达出像单号等于"PO123"或是名字包含"中国"这样的条件了。
但这只是一个良好的开始而已,实际业务中我们很可能用像 {数量}*{单价}>{值} 或是 {单价}*(1-{折扣}/100)>{值} 这样的条件,那么如何实现呢?
 
【因子、算式抽象过程】
是时候对我们的设计进行抽象了,我们将参与表达式计算或条件比较的元素都定义为因子,字段、常量都是具体的因子类型,两个因子的数学运算称为一个算式。
那么我们该怎么实现复杂算式的表达呢?
我们可以将算式定义为一种特定类型的因子,地位与字段、常量平级,这样算式中就可以包含子算式、字段或常量。如下图:
 
算式就可以被抽象为两个因子之间以算术运算符连接的关系:{因子}.算术运算({因子})。
 
算式以左子树优先二叉树表式为:
 
这样一来,我们就可以很方便的表示如前面提到的{单价}*(1-{折扣}/100)这样的算式了:
 
OK,有了算式的设计,我们可以表达因子间复杂的计算了,下面我们开始对条件进行设计。
有了前面的经验,我们的设计会顺利很多,我们将条件抽象为两个因子的关系运算,这是水到渠成的事。那么该怎样设计多个条件的组合呢?
 
如果大家对前面因子的抽象过程融会贯通了的话,要做出这个设计并不难,不妨停下来先想想你会怎么设计实现。
【组合条件的实现】
简单的条件以左子树优先的二叉树表示为:
 
两个条件的组合定义为一个新类"条件对",以左子树优先的二叉树表示为:
"条件对"将对左条件和右条件执行指定的逻辑运算(AND/OR/NOT),因为左(右)条件本身又可以为条件对,所以可以满足复杂的条件组合。
 
下面我们来定义一个简单的查询

查询对象:订单

查询条件:订单编号以”PO”打头 且 总订购金额/总订购数量(即平均单价)>=5500的订单

 
【对于关联实体(表)的查询】
我们经常会用到诸如找出某个供应商的订单或是订购了某类产品的订单,我们要获取的是订单对象,但条件针对的是订单对象的关联对象,我们该怎样满足这样的条件查询呢?
我能想到是首先对字段因子进行重构,字段因子应不仅能表达其字段名称还要能够表达完整路径(如订单.订购项.产品.编码),如此我们就便能这样表示"包含有编码以A开头的产品订购项的订单":

{订单.订购项.产品.编码}.StartsWith("A")
这样在编译器编译查询对象时,将字段的完整路径逐级展开进行解析,生成相应的SQL脚本或是Linq语句即可实现关联查询。

 

下面我们来定义两个稍微复杂的查询

查询对象:订单

查询条件:供应商编号以”S”打头 且 存在订购明细中单价*订单折扣(即折后单价)>=5000的订单

查询对象:订单

查询条件:({订单编号}以”PO”开头 或 {订单日期}不大于等于2014-1-1) 且 存在产品编码为”A1”的产品订购记录 且 订购明细中各项订购数量小于订单总订购数量

 

【写在最后】

博文除了图片以外绝大部分文字内容都是我在上下班乘坐地铁或公交时在手机上完成的,写作不昜,如果对你还有点用处或启发的话,望不吝点,谢谢!

 

(原创)通用查询实现方案(可用于DDD)[附源码] -- 设计思路的更多相关文章

  1. 通用查询实现方案(可用于DDD)[附源码] -- 设计思路

    原文:通用查询实现方案(可用于DDD)[附源码] -- 设计思路 [声明] 写作不易,转载请注明出处(http://www.cnblogs.com/wiseant/p/3988592.html).   ...

  2. (原创)通用查询实现方案(可用于DDD)[附源码] -- 简介

    [声明] 写作不易,转载请注明出处(http://www.cnblogs.com/wiseant/p/3985353.html).   [系列文章] 通用查询实现方案(可用于DDD)[附源码] -- ...

  3. 通用查询实现方案(可用于DDD)[附源码] -- 简介

    原文:通用查询实现方案(可用于DDD)[附源码] -- 简介 [声明] 写作不易,转载请注明出处(http://www.cnblogs.com/wiseant/p/3985353.html).   [ ...

  4. python多线程爬取-今日头条的街拍数据(附源码加思路注释)

    这里用的是json+re+requests+beautifulsoup+多线程 1 import json import re from multiprocessing.pool import Poo ...

  5. 开源方案搭建可离线的精美矢量切片地图服务-8.mapbox 之sprite大图图标文件生成(附源码)

    项目成果展示(所有项目文件都在阿里云的共享云虚拟主机上,访问地图可以会有点慢,请多多包涵). 01:中国地图:http://test.sharegis.cn/mapbox/html/3china.ht ...

  6. C#进阶系列——一步一步封装自己的HtmlHelper组件:BootstrapHelper(三:附源码)

    前言:之前的两篇封装了一些基础的表单组件,这篇继续来封装几个基于bootstrap的其他组件.和上篇不同的是,这篇的有几个组件需要某些js文件的支持. 本文原创地址:http://www.cnblog ...

  7. 轻量级通信引擎StriveEngine —— C/S通信demo(2) —— 使用二进制协议 (附源码)

    在网络上,交互的双方基于TCP或UDP进行通信,通信协议的格式通常分为两类:文本消息.二进制消息. 文本协议相对简单,通常使用一个特殊的标记符作为一个消息的结束. 二进制协议,通常是由消息头(Head ...

  8. C#轻量级通通讯组件StriveEngine —— C/S通信开源demo(2) —— 使用二进制协议 (附源码)

    前段时间,有几个研究ESFramework通信框架的朋友对我说,ESFramework有点庞大,对于他们目前的项目来说有点“杀鸡用牛刀”的意思,因为他们的项目不需要文件传送.不需要P2P.不存在好友关 ...

  9. 【转】.NET(C#):浅谈程序集清单资源和RESX资源 关于单元测试的思考--Asp.Net Core单元测试最佳实践 封装自己的dapper lambda扩展-设计篇 编写自己的dapper lambda扩展-使用篇 正确理解CAP定理 Quartz.NET的使用(附源码) 整理自己的.net工具库 GC的前世与今生 Visual Studio Package 插件开发之自动生

    [转].NET(C#):浅谈程序集清单资源和RESX资源   目录 程序集清单资源 RESX资源文件 使用ResourceReader和ResourceSet解析二进制资源文件 使用ResourceM ...

随机推荐

  1. 解决linux 无法下载 oracle 官网 java的 安装包

    wget --no-cookies --no-check-certificate --header "Cookie: oraclelicense=accept-securebackup-co ...

  2. 11.用C对32位内存地址的访问方式

    使用一个32位处理器,要对一个32位的内存地址进行访问,可以这样定义 #define RAM_ADDR     (*(volatile unsigned long *)0x0000555F)      ...

  3. asp.net mvc4 Html.BeginForm表单提交

    默认是get提交,如果是post提交需要在控制器ActionResult上加:[AcceptVerbs(HttpVerbs.Post)] 举例: 在HelpController中,会定义如下的Acti ...

  4. Convert HTML to Text(转载)

    原文地址:http://www.blackbeltcoder.com/Articles/strings/convert-html-to-text  Download Source Code Intro ...

  5. Excel实用技巧

    情景:有时候,我们写了一个公式,然后想在其他行也套用这个公式,一般人都是把鼠标放在那个公式所在的单元格的右下角,然后往下拉,数据量少的时候还好,数据量大的时候就不太好操作了,此时,我们需要一个好方法. ...

  6. 基于AQS的锁

    锁分为独占锁和共享锁,它们的主要实现都是依靠AbstractQueuedSynchronizer,这个类只提供一系列公共的方法,让子类来调用.基于我了解不深,从这个类的属性,方法,和独占锁的获取方式去 ...

  7. 00904. 00000 - "%s: invalid identifier"

    SELECT * FROM table name WHERE STRING_VALUE like '%Britaney Searing%' ORDER BY COMPOSITE_INSTANCE_ID ...

  8. eclipse:不能在tomcat里添加一个项目的解决方法

    Cannot add a project to a tomcat server in eclipse You didn't create your project as "Dynamic W ...

  9. Sql Server 2012 Enterprise Edition 企业版 迅雷 下载地址

    Sql Server 2012 Enterprise Edition 企业版 迅雷 下载地址 版本号 cn_sql_server_2012_enterprise_edition_x86_x64_dvd ...

  10. nagios二次开发(五)---nagios和nagiosql的关系

    根据对nagios和nagiosql的了解,笔者简要的将二者的关系粗略的梳理了一下,具体情况如下图所示: 从上面的关系图中可以看出,nagios与nagiosql共享了主机.主机组.服务.服务组等.c ...