在做查询时,经常遇到一类需求。请看下面的SQL语句查询

SELECT * FROM Company
WHERE CompanyCode='Kingston' AND Suspended='N' AND DbServer='James\SQLEXPRESS'
 

这里有三个条件,在界面中,也就是我们需要增加三个控件来供用户输入值,再拼接成SQL发送到服务器。

再来看一下界面中的情况,根据客户名称,下单日期,是否过帐,是否完成4个选项来读取发票信息

点击Refresh按钮之后,产生的SQL条件,可能像下面这样写的一样

SELECT  *  FROM Invoce WHERE  Customer='A'  and IssueDate='2013-06-16' and  Posted='Y' and Closed='N'
 

现在遇到的问题时,读取界面中的控件的用户输入值,转化为SQL条件,需要经历一些复杂的重复的操作。

如果用户在这四个控件不输入任何值,那么生成的SQL语句应该直接是

SELECT  *  FROM Invoce

.csharpcode, .csharpcode pre
{
font-size: small;
color: black;
font-family: consolas, "Courier New", courier, monospace;
background-color: #ffffff;
/*white-space: pre;*/
}
.csharpcode pre { margin: 0em; }
.csharpcode .rem { color: #008000; }
.csharpcode .kwrd { color: #0000ff; }
.csharpcode .str { color: #006080; }
.csharpcode .op { color: #0000c0; }
.csharpcode .preproc { color: #cc6633; }
.csharpcode .asp { background-color: #ffff00; }
.csharpcode .html { color: #800000; }
.csharpcode .attr { color: #ff0000; }
.csharpcode .alt
{
background-color: #f4f4f4;
width: 100%;
margin: 0em;
}
.csharpcode .lnum { color: #606060; }如果用户只想通过发票日期来过滤,则SQL语句应该是这样的

SELECT  *  FROM Invoce WHERE IssueDate='2013-06-16'

.csharpcode, .csharpcode pre
{
font-size: small;
color: black;
font-family: consolas, "Courier New", courier, monospace;
background-color: #ffffff;
/*white-space: pre;*/
}
.csharpcode pre { margin: 0em; }
.csharpcode .rem { color: #008000; }
.csharpcode .kwrd { color: #0000ff; }
.csharpcode .str { color: #006080; }
.csharpcode .op { color: #0000c0; }
.csharpcode .preproc { color: #cc6633; }
.csharpcode .asp { background-color: #ffff00; }
.csharpcode .html { color: #800000; }
.csharpcode .attr { color: #ff0000; }
.csharpcode .alt
{
background-color: #f4f4f4;
width: 100%;
margin: 0em;
}
.csharpcode .lnum { color: #606060; }或者是其它的情况,因为WHERE部分的条件出现的时机不确定,所以我们产生的SQL通常是这样的,在考虑全部情况

SELECT  *  FROM Invoce WHERE 1=1 
AND   Customer='A'  and IssueDate='2013-06-16' and  Posted='Y' and Closed='N'
 
 

.csharpcode, .csharpcode pre
{
font-size: small;
color: black;
font-family: consolas, "Courier New", courier, monospace;
background-color: #ffffff;
/*white-space: pre;*/
}
.csharpcode pre { margin: 0em; }
.csharpcode .rem { color: #008000; }
.csharpcode .kwrd { color: #0000ff; }
.csharpcode .str { color: #006080; }
.csharpcode .op { color: #0000c0; }
.csharpcode .preproc { color: #cc6633; }
.csharpcode .asp { background-color: #ffff00; }
.csharpcode .html { color: #800000; }
.csharpcode .attr { color: #ff0000; }
.csharpcode .alt
{
background-color: #f4f4f4;
width: 100%;
margin: 0em;
}
.csharpcode .lnum { color: #606060; }

为了解决这一类问题,下面解释一下,我所遇到到的最好的办法。

设计object control,如下图中所示。添加EntityName和FieldName

.csharpcode, .csharpcode pre
{
font-size: small;
color: black;
font-family: consolas, "Courier New", courier, monospace;
background-color: #ffffff;
/*white-space: pre;*/
}
.csharpcode pre { margin: 0em; }
.csharpcode .rem { color: #008000; }
.csharpcode .kwrd { color: #0000ff; }
.csharpcode .str { color: #006080; }
.csharpcode .op { color: #0000c0; }
.csharpcode .preproc { color: #cc6633; }
.csharpcode .asp { background-color: #ffff00; }
.csharpcode .html { color: #800000; }
.csharpcode .attr { color: #ff0000; }
.csharpcode .alt
{
background-color: #f4f4f4;
width: 100%;
margin: 0em;
}
.csharpcode .lnum { color: #606060; }

在运行时,以下面的代码获取它产生的SQL语句条件

efcCustomerNo.GetPredicateExpression();
 

这样设计方法,考虑了以下几种情况

1  当用户不在控件中输入任何值时,上面的原代码不返回任何条件。

2 用户想输入一个范围内的值,输入两个值之后,产生 BETWEEN A AND B条件

3 用户想输入一个唯一的过滤条件值,输入一个值A,产生条件 CustomerNo=’A’

依据查询的可能,还有可能是like,模糊查询。请看下面的枚举值

public enum ReportFieldSelectionCondition
{
[DisplayText("All")]
All = 0,
[DisplayText("Equal")]
Equal = 1,
[DisplayText("Exclude")]
Exclude = 6,
[DisplayText("Include")]
Include = 5,
[DisplayText("In Range")]
InRange = 3,
[DisplayText("Like")]
Like = 7,
[DisplayText("Not Equal")]
NotEqual = 2,
[DisplayText("Not Like")]
NotLike = 8,
[DisplayText("Out Range")]
OutRange = 4
}

.csharpcode, .csharpcode pre
{
font-size: small;
color: black;
font-family: consolas, "Courier New", courier, monospace;
background-color: #ffffff;
/*white-space: pre;*/
}
.csharpcode pre { margin: 0em; }
.csharpcode .rem { color: #008000; }
.csharpcode .kwrd { color: #0000ff; }
.csharpcode .str { color: #006080; }
.csharpcode .op { color: #0000c0; }
.csharpcode .preproc { color: #cc6633; }
.csharpcode .asp { background-color: #ffff00; }
.csharpcode .html { color: #800000; }
.csharpcode .attr { color: #ff0000; }
.csharpcode .alt
{
background-color: #f4f4f4;
width: 100%;
margin: 0em;
}
.csharpcode .lnum { color: #606060; }

查询条件的几种情况,它都考虑到。根据这些情况,产生不同的SQL条件部分,供程序调用。

控件的基础代码稍微有些复杂,以Between为例子,代码像这样所示

if (!flag)
{
expression.Add((IPredicate) (field >= valueFrom));
}
if (!flag2)
{
expression.Add((IPredicate) (field <= valueTo));
}

.csharpcode, .csharpcode pre
{
font-size: small;
color: black;
font-family: consolas, "Courier New", courier, monospace;
background-color: #ffffff;
/*white-space: pre;*/
}
.csharpcode pre { margin: 0em; }
.csharpcode .rem { color: #008000; }
.csharpcode .kwrd { color: #0000ff; }
.csharpcode .str { color: #006080; }
.csharpcode .op { color: #0000c0; }
.csharpcode .preproc { color: #cc6633; }
.csharpcode .asp { background-color: #ffff00; }
.csharpcode .html { color: #800000; }
.csharpcode .attr { color: #ff0000; }
.csharpcode .alt
{
background-color: #f4f4f4;
width: 100%;
margin: 0em;
}
.csharpcode .lnum { color: #606060; }代码的意图明了,第一个控件中有值时,产生<=的表达式,第二个控件中有值时,产生>=的条件。

有三种类型的object control,字符串类型,日期类型和bool类型,上面的图中有全部显示。

字符串类型经常遇到,这篇文章中解释了这个类型的控件,日期类型与字符串相似,产生的条件是日期的比较操作。

bool类型是为了解决一些值,真/假的情况。比如是否过帐,日记帐是否完成。控件有二个基本的属性

   [DefaultValue(""), EditorBrowsable(EditorBrowsableState.Always),  Browsable(true)]
public string EntityName
{
get
{
return this._entityName;
}
set
{
this._entityName = value;
}
} [EditorBrowsable(EditorBrowsableState.Always), Browsable(true), DefaultValue("")]
public string FieldName
{
get
{
return this._fieldName;
}
set
{
this._fieldName = value;
}
}

.csharpcode, .csharpcode pre
{
font-size: small;
color: black;
font-family: consolas, "Courier New", courier, monospace;
background-color: #ffffff;
/*white-space: pre;*/
}
.csharpcode pre { margin: 0em; }
.csharpcode .rem { color: #008000; }
.csharpcode .kwrd { color: #0000ff; }
.csharpcode .str { color: #006080; }
.csharpcode .op { color: #0000c0; }
.csharpcode .preproc { color: #cc6633; }
.csharpcode .asp { background-color: #ffff00; }
.csharpcode .html { color: #800000; }
.csharpcode .attr { color: #ff0000; }
.csharpcode .alt
{
background-color: #f4f4f4;
width: 100%;
margin: 0em;
}
.csharpcode .lnum { color: #606060; }如果接触过ORM的查询的写法,可能有很多代码像下面这样

 if (!AllowViewAllTransaction)
args.PredicateBucket.PredicateExpression.Add(AccountsReceivableInvoiceFields.CreatedBy == Shared.CurrentUser.Userid); if (!Shared.CurrentUserSession.AllowAccessAllCustomers)
args.PredicateBucket.PredicateExpression.Add(Shared.GetAllowedCustomerNoPredicateExpression(AccountsReceivableInvoiceFields.CustomerNo)); if (_show)
{
_peCustomerNo = this.efcCustomerNo.GetPredicateExpression();
_pePostedFilter = this.efcPostedFilter.GetPredicateExpression();
_peIssueDate = this.efcIssueDate.GetPredicateExpression();
_peClosedFilter = this.efcClosedFilter.GetPredicateExpression(); FetchAccountsReceivableInvoice();
}

.csharpcode, .csharpcode pre
{
font-size: small;
color: black;
font-family: consolas, "Courier New", courier, monospace;
background-color: #ffffff;
/*white-space: pre;*/
}
.csharpcode pre { margin: 0em; }
.csharpcode .rem { color: #008000; }
.csharpcode .kwrd { color: #0000ff; }
.csharpcode .str { color: #006080; }
.csharpcode .op { color: #0000c0; }
.csharpcode .preproc { color: #cc6633; }
.csharpcode .asp { background-color: #ffff00; }
.csharpcode .html { color: #800000; }
.csharpcode .attr { color: #ff0000; }
.csharpcode .alt
{
background-color: #f4f4f4;
width: 100%;
margin: 0em;
}
.csharpcode .lnum { color: #606060; }

PredicationExpress类型相当于 CustomerNo=’A’ 这样的条件的面向对象的封装,最终产生的SQL条件,与开头的一样,这个过程由ORM框架来负责产生,根据类型及其属性,产生对应的SQL语句。

如果没有应用ORM工具,缺少entityName和fieldName,同样也可以应用这里介绍的技术,直接用SQL表名和字段名即可,再根据各种条件组合判断,产生不同的查询条件。

应用本文中的方法,在做查询类程序时,可以节省大量的重复的代码。

企业管理软件开发架构之七 Object Control设计与运用的更多相关文章

  1. python基础(29):网络编程(软件开发架构、网络基础、套接字初使用)

    1. 软件开发架构 我们了解的程序之间通讯的应用可分为两种: 第一种是应用类:qq.微信.百度网盘.腾讯视频这一类是属于需要安装的桌面应用. 第二种是web类:比如百度.知乎.博客园等使用浏览器访问就 ...

  2. python网络编程-Json序列化功能扩展-软件开发架构-OSI七层协议-TCP-01

    面向对象补充知识点(面向对象的应用) 扩展json序列化所支持的数据类型(分析源码) import json from datetime import datetime, date # ------- ...

  3. 软件开发架构,网络编程简介,OSI七层协议,TCP和UDP协议

    软件开发架构 什么是软件开发架构 1.软件架构是一个系统的草图. 2.软件架构描述的对象是直接构成系统的抽象组件. 3.各个组件之间的连接则明确和相对细致地描述组件之间的通讯. 4.在实现阶段,这些抽 ...

  4. 软件开发架构介绍||OSI七层协议之物理层、数据链路层、网络层、传输层(mac地址、ip协议、断开协议、tcp协议之三次握手四次挥手)

    一.网络编程 软件开发架构 C/S架构 C:客户端 想体验服务的时候才会去找服务端体验服务 S:服务端   24小时不间断的提供服务,即时监听,随时待命 B/S架构 B:浏览器    想体验服务的时候 ...

  5. 软件开发架构与网络之OSI七层协议(五层)

    本期内容概要 python回顾 软件开发架构 网络理论前瞻 osi七层协议(五层) 以太网协议 IP协议 port协议 交换机 路由器 局域网 广域网 TCP协议 三次握手 四次挥手 UDP协议 内容 ...

  6. 1、网络并发编程--简介、软件开发架构、OSI七层协议

    python复习 变量与常量 基本数据类型 内置方法 字符编码.文件操作 函数 函数参数.闭包函数.装饰器 面向对象 封装.继承.多态 """ 什么是对象 数据与功能的结 ...

  7. 软件开发架构、网络基础知识、osi七层模型

    一.软件开发的架构 涉及到两个程序之间通讯的应用大致可以分为两种: 第一种是应用类:qq.微信.网盘.优酷这一类是属于需要安装的桌面应用 第二种是web类:比如百度.知乎.博客园等使用浏览器访问就可以 ...

  8. PSP个人软件开发系统面向对象需求分析与设计文档

    1.引言 1.1编写的目的 编写该文档的目的是,对产品进行定义,详尽说明该产品的软件需求,简述我们对 PSP个人软件开发系统的初步设想,及划分的各功能模块以及各模块的实体图和数据流图. 1.2预期的读 ...

  9. 一般软件开发流程和BBS表设计

    项目开发流程 需求分析 架构师+产品经理+开发组组长 和客户公司谈需求之前 ,事先需要想一下这个项目要怎么做 里面的坑点提前想好比较简单的解决方案 在跟客户谈的时候有意识的引导客户朝你已经想好的方案上 ...

随机推荐

  1. Xcode模拟器启动不了,修复ios模拟器

    1.如果可以重置模拟器 首先试试重置模拟器 2.如果不能重置,可以选择使用如下命令杀死模拟器服务: killall -9 com.apple.CoreSimulator.CoreSimulatorSe ...

  2. Android权限管理之RxPermission解决Android 6.0 适配问题

    前言: 上篇重点学习了Android 6.0的运行时权限,今天还是围绕着Android 6.0权限适配来总结学习,这里主要介绍一下我们公司解决Android 6.0权限适配的方案:RxJava+RxP ...

  3. Xamarin+Prism小试牛刀:定制跨平台Outlook邮箱应用(后续)

    在[Xamarin+Prism小试牛刀:定制跨平台Outlook邮箱应用]里面提到了Microsoft 身份认证,其实这也是一大块需要注意的地方,特作为后续补充这些知识点.上章是使用了Microsof ...

  4. pt-online-schema-change中update触发器的bug

    pt-online-schema-change在对表进行表结构变更时,会创建三个触发器. 如下文测试案例中的t2表,表结构如下: mysql> show create table t2\G . ...

  5. WPF样式之画刷结合样式

    第一种画刷,渐变画刷GradientBrush (拿线性渐变画刷LinearGradientBrush(其实它涵盖在GradientBrush画刷内.现在拿他来说事.),还有一个圆心渐变画刷Radia ...

  6. Response.Redirect引起的性能问题分析

    现象: 最近做的一个系统通过单点登录(SSO) 技术验证用户登录.用户在SSO 系统上通过验证后,跳转到该系统的不同模块.而跳转的时间一直维持子啊几分钟左右. 分析步骤: 在问题复现时抓取Hang d ...

  7. Node.js npm 详解

    一.npm简介 安装npm请阅读我之前的文章Hello Node中npm安装那一部分,不过只介绍了linux平台,如果是其它平台,有前辈写了更加详细的介绍. npm的全称:Node Package M ...

  8. JAVA构造时成员初始化的陷阱

    让我们先来看两个类:Base和Derived类.注意其中的whenAmISet成员变量,和方法preProcess(). 情景1:(子类无构造方法) class Base { Base() { pre ...

  9. ThinkPHP 模板substr的截取字符串函数

    ThinkPHP 模板substr的截取字符串函数在Common/function.php加上以下代码 /** ** 截取中文字符串 **/ function msubstr($str, $start ...

  10. 中国CIO最关心的八大问题(下)

    中国CIO最关心的八大问题(下) 从调研数据还可以看出,在企业级IT建设与投资上,CIO们并非是一群狂热的技术信徒,他们更多的是从企业发展阶段.信息化程度.技术成熟度.ROI等方面进行综合评估. 五. ...