zoukankan      html  css  js  c++  java
  • 企业管理软件开发架构之七 Object Control设计与运用

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

    SELECT * FROM Company
    WHERE CompanyCode='Kingston' AND Suspended='N' AND DbServer='JamesSQLEXPRESS'
     

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

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

    image

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

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

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

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

    SELECT  *  FROM Invoce

    如果用户只想通过发票日期来过滤,则SQL语句应该是这样的

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

    或者是其它的情况,因为WHERE部分的条件出现的时机不确定,所以我们产生的SQL通常是这样的,在考虑全部情况

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

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

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

    image

    在运行时,以下面的代码获取它产生的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
        }

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

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

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

    代码的意图明了,第一个控件中有值时,产生<=的表达式,第二个控件中有值时,产生>=的条件。

    有三种类型的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;
                }
            }

    如果接触过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();
                }

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

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

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

  • 相关阅读:
    微信开发:消息回复总结
    *** wechat-php-sdk 微信公众平台php开发包
    **微信接入探秘(一)——从零认识微信接口(主动接口和被动接口)
    《30天自制操作系统》笔记(01)——hello bitzhuwei’s OS!【转】
    Linux进程调度原理【转】
    Linux进程核心调度器之主调度器schedule--Linux进程的管理与调度(十九)【转】
    Tslib触摸屏官网【转】
    Tslib的移植【转】
    Linux Kernel代码艺术——数组初始化【转】
    Linux 内核进程管理之进程ID【转】
  • 原文地址:https://www.cnblogs.com/JamesLi2015/p/3149263.html
Copyright © 2011-2022 走看看