组合查询(机房重构知识点总结)

历经n多天,组合查询模板终于做完了,总结一下这几天的成果,和大家一起学习交流。

先看一下父窗体的关键代码:

父窗体代码:

Public Class frmComboQuery
    Protected Overridable Sub frmComboQuery_Load(sender As Object, e As EventArgs) Handles MyBase.Load

        Dim ComboxArray(4) As ComboBox            '定义控件数组,获取组合框
        ComboxArray(0) = cboOperator1
        ComboxArray(1) = cboOperator2
        ComboxArray(2) = cboOperator3
        ComboxArray(3) = cboRelation1
        ComboxArray(4) = cboRelation2
        CommonMethod.SelectIndex(ComboxArray)           '设置combox默认显示第一项

        Dim ControlArray(6) As Control            '定义控件数组,获取组合2和组合3的控件
        ControlArray(0) = cboField2
        ControlArray(1) = cboOperator2
        ControlArray(2) = txtContent2
        ControlArray(3) = cboRelation2
        ControlArray(4) = cboField3
        ControlArray(5) = cboOperator3
        ControlArray(6) = txtContent3
        CommonMethod.LockControlArray(ControlArray)        '调用共有方法,锁定控件
    End Sub

    Private Sub btnQuery_Click(sender As Object, e As EventArgs) Handles btnQuery.Click
        Try
            Dim ControlArray(2) As Control             '定义控件数组,获取组合1的控件
            ControlArray(0) = cboField1
            ControlArray(1) = cboOperator1
            ControlArray(2) = txtContent1

            If CommonMethod.IsEmptyControlArray(ControlArray) = False Then           '判断组合1的控件是否为空
                Exit Sub
            End If

            If cboRelation1.Text.Trim <> "<请选择>" Then                '组合关系1不为空时
                ControlArray(0) = cboField2                   '获取组合2的控件
                ControlArray(1) = cboOperator2
                ControlArray(2) = txtContent2

                If CommonMethod.IsEmptyControlArray(ControlArray) = False Then      '判断组合2的条件是否为空
                    Exit Sub
                End If

                If cboRelation2.Text.Trim <> "<请选择>" Then                 '组合关系2不为空时
                    ControlArray(0) = cboField3                     '获取组合3的控件
                    ControlArray(1) = cboOperator3
                    ControlArray(2) = txtContent3

                    If CommonMethod.IsEmptyControlArray(ControlArray) = False Then     '判断组合3的条件是否为空
                        Exit Sub
                    End If
                End If
            End If

            Dim eComboQuery1 As New Entity.ComboQueryEntity       '定义组合查询实体,将条件传入实体
            eComboQuery1.dbName = GetdbName()
            eComboQuery1.Field1 = cboField1.Text.Trim
            eComboQuery1.Field2 = cboField2.Text.Trim
            eComboQuery1.Field3 = cboField3.Text.Trim
            eComboQuery1.Operator1 = cboOperator1.Text.Trim
            eComboQuery1.Operator2 = cboOperator2.Text.Trim
            eComboQuery1.Operator3 = cboOperator3.Text.Trim
            eComboQuery1.Content1 = txtContent1.Text.Trim
            eComboQuery1.Content2 = txtContent2.Text.Trim
            eComboQuery1.Content3 = txtContent3.Text.Trim
            eComboQuery1.Relation1 = cboRelation1.Text.Trim
            eComboQuery1.Relation2 = cboRelation2.Text.Trim

            Dim dtComboQuery As New DataTable
            Dim mgr As New BLL.ComboQueryBLL
            dtComboQuery = mgr.ComboQuery(eComboQuery1)

            dgvRecord.DataSource = dtComboQuery
        Catch ex As Exception
            MessageBox.Show(ex.Message.ToString())
            dgvRecord.DataSource = Nothing
        End Try
    End Sub
    Protected Overridable Function GetdbName() As String
        Return ""
    End Function
    Private Sub cboRelation1_SelectedIndexChanged(sender As Object, e As EventArgs) Handles cboRelation1.SelectedIndexChanged
        Dim ControlArray(3) As Control                   '定义控件数组,获取组合2的控件和组合关系2的控件,
        ControlArray(0) = cboField2
        ControlArray(1) = cboOperator2
        ControlArray(2) = txtContent2
        ControlArray(3) = cboRelation2
        If cboRelation1.SelectedIndex = 0 Then               '如果组合关系1为空,清空组合2和组合关系2
            CommonMethod.ClearControlArray(ControlArray)
            CommonMethod.LockControlArray(ControlArray)
        Else
            CommonMethod.UnLockControlArray(ControlArray)                 '否则,解锁组合2和组合关系2
        End If
    End Sub

    Private Sub cboRelation2_SelectedIndexChanged(sender As Object, e As EventArgs) Handles cboRelation2.SelectedIndexChanged
        Dim ControlArray(2) As Control                   '定义控件数组,获取组合3的控件
        ControlArray(0) = cboField3
        ControlArray(1) = cboOperator3
        ControlArray(2) = txtContent3
        If cboRelation2.SelectedIndex = 0 Then               '如果组合关系2为空,清空组合2,锁定组合3
            CommonMethod.ClearControlArray(ControlArray)
            CommonMethod.LockControlArray(ControlArray)
        Else
            CommonMethod.UnLockControlArray(ControlArray)                '否则,解锁组合3
        End If
    End Sub
End Class

文中调用的公共方法上篇博客已写,这里不再重复。

现在以查询操作员工作记录为例:

Public Class frmWorkLog
    Protected Overrides Sub frmComboQuery_Load(sender As Object, e As EventArgs)
        MyBase.frmComboQuery_Load(sender, e)
        Dim ComboxArray(2) As ComboBox           '定义控件数组,获取组合框
        ComboxArray(0) = cboField1
        ComboxArray(1) = cboField2
        ComboxArray(2) = cboField3
        CommonMethod.SelectIndex(ComboxArray)           '设置combox默认显示第一项
    End Sub
    Protected Overrides Function GetdbName() As String
        Return "WorkLog"
    End Function
End Class

说明:1.设置默认第一项在父窗体添加了一部分,这里是字段的那部分,因为字段是在子窗体添加,所以如果这段代码也放父窗体会报错。2.这里通过传递一个字符串来通知D层确定哪一个数据表,这里是我感觉不好的地方,但是暂时没有想到其他方法,只能先这么写。

B层代码:

Public Class ComboQueryBLL
    Dim factory As New Factory.DataAccess
    Public Function ComboQuery(ByVal cboworklog As Entity.ComboQueryEntity) As DataTable
        Dim iComboQuery As IDAL.IComboQuery
        iComboQuery = factory.CreateComboQuery

        Dim dtComboQuery As New DataTable
        dtComboQuery = iComboQuery.ComboQuery(cboworklog)

        If dtComboQuery.Rows.Count = 0 Then
            Throw New Exception("没有记录")
        Else
            Return dtComboQuery
        End If
    End Function
End Class

D层代码:

Imports System.Data.SqlClient
Public Class SqlServerComboQueryDAL : Implements IDAL.IComboQuery

    Dim sqlhelper As New SqlHelper

    Public Function ComboQuery1(cboworklog As Entity.ComboQueryEntity) As DataTable Implements IDAL.IComboQuery.ComboQuery
        Dim ecboworklog As New Entity.ComboQueryEntity
        Select Case cboworklog.dbName
            Case "WorkLog"
                ecboworklog = Method.SwitchWorklogField(cboworklog)            '调用方法,转换字段,以匹配数据库
            Case "StudentAccount"
                ecboworklog = Method.SwitchStudentAccount(cboworklog)
        End Select

        Dim sqlParameter As SqlParameter()
        sqlParameter = New SqlParameter() {
        New SqlParameter("@dbName", ecboworklog.dbName),
        New SqlParameter("@Field1", ecboworklog.Field1),
        New SqlParameter("@Field2", ecboworklog.Field2),
        New SqlParameter("@Field3", ecboworklog.Field3),
        New SqlParameter("@Operator1", ecboworklog.Operator1),
        New SqlParameter("@Operator2", ecboworklog.Operator2),
        New SqlParameter("@Operator3", ecboworklog.Operator3),
        New SqlParameter("@Content1", ecboworklog.Content1),
        New SqlParameter("@Content2", ecboworklog.Content2),
        New SqlParameter("@Content3", ecboworklog.Content3),
        New SqlParameter("@Relation1", ecboworklog.Relation1),
        New SqlParameter("@Relation2", ecboworklog.Relation2)}

        Dim dtComboQuery As New DataTable
        dtComboQuery = sqlhelper.Query("sp_ComboQuery", CommandType.StoredProcedure, sqlParameter)

        Return dtComboQuery
    End Function
End Class

存储过程代码:

USE [ChargeSystem]
GO
/****** Object:  StoredProcedure [dbo].[sp_ComboQuery]    Script Date: 2014/6/22 16:40:59 ******/
SET ANSI_NULLS ON
GO
SET QUOTED_IDENTIFIER ON
GO
-- =============================================
-- Author:		刘晓春
-- Create date: 2014年6月17日
-- Description:	组合查询
-- =============================================
CREATE PROCEDURE [dbo].[sp_ComboQuery]
	@dbName varchar(20),
	@field1 varchar(20),@operator1 varchar(20),@content1 varchar(20),
	@relation1 varchar(10),
	@field2 varchar(20),@operator2 varchar(20),@content2 varchar(20),
	@relation2 varchar(20),
	@field3 varchar(20),@operator3 varchar(20),@content3 varchar(20)

AS
BEGIN
	DECLARE @sqlText varchar(200)
	SET @sqlText='SELECT * FROM '[email protected]+' WHERE ' [email protected] [email protected]+char(39) + @content1 + char(39)
		if @relation1<>''
		BEGIN
				SET @[email protected][email protected]+CHAR(32)[email protected][email protected]+CHAR(39)[email protected]+CHAR(39)
				if @relation2<>''
				BEGIN
				SET @[email protected][email protected]+CHAR(32)[email protected][email protected]+CHAR(39)[email protected]+CHAR(39)
				END
		END
	EXECUTE(@sqlText)
END

效果如下:

题外话:

因为系统多次用到组合查询,而且各个窗体非常类似,所以最初只是想到用窗体的继承,免得做重复的窗体。后来父窗体做好之后,发现那些判断是否为空、清空等代码可以写到父窗体,然后子窗体写关于查询的代码。

紧接着就出现了一个问题,使用窗体继承,对于同一个事件而言,程序会先执行父窗体中的代码,后执行子窗体中的代码。在我的程序里,当执行按钮的click事件时,父窗体会先判断组合框是否为空,如果判断出为空,给出了提示,当点完确定后,程序并没有像想象中那样停下来让你选择组合框,而是接着执行子窗体的查询。

后来只好请教师父和师哥,得到一个解决办法,就是声明一个全局变量,由它通知子窗体是否执行,同时师哥指出,其实子窗体的代码也可以放在父窗体中,我自己也觉得声明全局变量感觉不好,所以就演化到现在的样子了,后来才知道,不知不觉还用了一个设计模式,模板方法模式。

不过这个模式依然需要子窗体去传递一个参数,让D层去判断是用的哪一个数据库,感觉不好,但是也没有想出好的办法,如果大家有什么好的建议,望不吝奉献。

组合查询(机房重构知识点总结)

时间: 2024-10-01 20:22:07

组合查询(机房重构知识点总结)的相关文章

判断文本框、组合框是否空(机房重构知识点总结)

机房重构进行时,多次用到判断文本框.组合框是否为空,以及清空文本框.组合框,为此专门抽象出一系列的方法,开始写的比较乱,昨天又重新理了一遍,拿来与大家交流学习. 上图是组合查询的界面,因为上篇讲到了窗体继承,所以故意选择组合查询的父窗体,以此为基础,谈一下怎样判断文本框.组合框是否为空,怎样清空文本框.组合框,同时作为窗体继承的实践,以及组合查询的前篇. 组合查询有三个条件,我们可以选择一个.两个或三个,这就需要我们去判断其中一部分文本框.组合框是否为空,怎么办?方法有两个,一是把需要判断的控件

史上最简洁的向上取整(机房重构知识点总结)

在机房收费系统的基本数据设定中,有一个单位递增时间,这就需要我们满足如下需求: 假如递增单位时间是5,那么需要实现如下的效果: 5-->5 6-->10 7-->10 11-->15 我们一步一步来,先看一个简单的例子: 2.0-->2 2.1-->3 2.4-->3 2.6-->3 我开始用的取整,然后加1,结果带有小数的可以达到目的,但这会让2.0变为3,怎么办呢?abs(int(-x)),先转换为负数,取整后再变为正数即可.因为int(),会让一个浮点

职责链模式应用——下机(机房重构知识点总结)

下机涉及两个方面,消费时间和消费金额. 对消费时间的处理用的是职责链模式,感觉这个模式用的非常妙,參考的师哥的博客:<机房收费下机中用到的策略与职责链解析>:消费金额的处理用策略模式.针对不同的用户类型. 这里着重介绍职责链的应用. 依据需求,将时间分为三个阶段,准备时间:不收取费用:至少上机时间:大于准备时间,小于至少上机时间的,一律按至少上机时间算.单位递增时间:大于至少上机时间后.按单位递增时间累加. TimeHandler类,定义一个处理请示的接口 Public MustInherit

重构—组合查询

组合查询是重构中的一个重点,也是比较麻烦的,但是我们可以用一个很好的办法来解决它,比如窗体继承,模板方法.关于窗体继承请参考博文:http://blog.csdn.net/augus3344/article/details/29384877 讲的很详细.这里主要说下模板方法,用这个方法可以为我们省掉很多繁琐的步骤和重复的代码.我们就以父窗体为模板,继承窗体来实现不同的模板,也就是将公共的代码写到模板中,自己特有的代码写到自己的模块,下面看代码. 父窗体的代码 U层代码 ImportsSystem

机房重构(5)——模板方法实现组合查询

在敲机房收费过程中,我们会发现很多窗体除了一些细微的差别外,基本是一模一样的,功能的实现也是大同小异.在第一次机房收费的时候,我们都是"好学生",尽管代码重复率极高,还是按部就班的一个个的实现.但在学习了设计模式,机房重构的现在,再傻傻的重复代码,就不是明智之举了. 整个收费系统中,总计有四个组合查询的功能(界面如图),为了提高代码复用率,提高效率,就引入了模板方法实现. 模板方法模式,定义了一个操作中的算法的骨架,把一些步骤延迟到子类当中.它使得子类可以不改变一个算法的结构即可重定义

机房重构---由组合查询引发的思考

前言: 不要基于代码编程,要基于图形进行软件设计. ---米老师 As mentionedabove,是上上个周四晚上锁门时候在小会议室听到米老师给九期师哥师姐讲系统时候的一句话,让我很是触动.Why? 有个问题不知道大家思考过没有,比如在<设计模式>学习过程中,我们照着代码"照葫芦画瓢"似的把代码敲了出来,貌似自己真的懂了,但是真正让自己去实践的时候,我们能做出来吗?或者在敲机房时候,有些难点我们是模仿"前人"博客做出来的,程序能跑起来了,代码自己也理

机房重构之模版方法模式-组合查询

机房收费系统中,一个比较让人纠结功能就是组合查询,不仅仅是代码比较多,而且大多都是重复的代码,也正是因为如此,才比较适合模版方法模式. 一.基本介绍 模版方式模式是定义一个操作中的算法的骨架,而将步骤延迟到子类中. 模板方法使得子类可以不改变一个算法的结构即可重定义算法的某些特定步骤. 类图 二.具体实现 1.建立模板父窗体 添加Windows窗体,设计模板界面(如下图),并在模板窗体里写入抽象出来的类和方法的代码. '**************************************

重构之路 组合查询之传递SQL字符串

既然是使用VB.NET语言对机房收费系统进行重构,那么无可避免的要去解决组合查询的问题,在VB版的实现中这是一个难点,不过大家还是依靠自己或者共同的智慧解决了这个看似复杂的问题. 如今编程的语言不同是一方面,更重要的是系统的结构不一样了,采用了三层架构去实现系统,这样一来就要考虑组合查询的在三层结构中的实现方法.当然,组合查询的核心办法是不变的,都是通过将查询的各个条件组装成SQL查询语句的where子句来实现的,问题就是这个where子句的组装在哪里完成? 如果放在U层完成,那么我们向下传递的

重构之路 组合查询之传参+存储过程

上篇博文给大家一起讨论了实现组合查询的一种方法,即在U层将select语句的where子句部分组装好,赋给一个字符串变量,传到D层然后与select子句组成完整的sql语句,之后执行,返回查询结果,就是这么简单,但是博文的结尾也留下了一个疑问,这种方法的安全性有点欠佳,有没有相对好一点的办法呢? 答案是肯定的,这次我们一起来看看我实现的另一种方法.首先给大家简单介绍一下这种方法的思路,其实也比较简单,最初我是想在程序代码里写sql查询语句的,然后将组合查询的各个条件的值当做实体参数(现在实体层定