导读:在机房重构中,有好些个查询都是大同小异,最为显著的就是组合查询了。怎样给自己省事儿,相同的东西能不能重复利用,就成了一个现实的问题。第一遍做机房的时候,使用的更多的是:复制+粘贴。学习了设计模式后,可以用模板方法解决。这篇文章,就通过窗体继承和模板方法,实现组合查询。

观点:组合查询在机房中有3中情况,其实,组合查询完全可以看到是一种查询情况。

一、窗体继承的使用



1,首先建立一个父窗体



2,添加一个新项



3,选择继承窗体



4,确定后,一个新的继承窗体就好了。

二、模板方法的使用



备注:定义一个组合查询的实体,方便传参

1,首先在U层写入基础方法和传参

<span style="font-size:18px;">Public Class FrmGroupQuery
Public enGroupQuery As New Model.GroupQueryM '定义一个实体参数
Private Sub Button1_Click_1(sender As Object, e As EventArgs) Handles btnQuery.Click '第一行组合关系为空
If cmbRelation1.Text = "" Then
'判断第一行控件内容是否为空
If cmbField1.Text = "" Then
MsgBox("请输入字段名") ElseIf cmbOperation1.Text = "" Then
MsgBox("请输入操作符") ElseIf txtContent1.Text = "" Then
MsgBox("请输入要查询的内容") End If
End If ' 当第一个组合关系不为空时
If cmbRelation1.Text <> "" Then
If cmbField1.Text = "" Then
MsgBox("请输入字段名")
ElseIf cmbOperation1.Text = "" Then
MsgBox("请输入操作符")
ElseIf txtContent1.Text = "" Then
MsgBox("请输入要查询的内容")
ElseIf cmbField2.Text = "" Then
MsgBox("请输入字段名")
ElseIf cmbOperation2.Text = "" Then
MsgBox("请输入操作符")
ElseIf txtContent2.Text = "" Then
MsgBox("请输入要查询的内容")
End If
End If ' 当第二个组合关系不为空时
If cmbRelation2.Text <> "" Then
If cmbField1.Text = "" Then
MsgBox("请输入字段名")
ElseIf cmbOperation1.Text = "" Then
MsgBox("请输入操作符")
ElseIf txtContent1.Text = "" Then
MsgBox("请输入要查询的内容")
ElseIf cmbField2.Text = "" Then
MsgBox("请输入字段名")
ElseIf cmbOperation2.Text = "" Then
MsgBox("请输入操作符")
ElseIf txtContent2.Text = "" Then
MsgBox("请输入要查询的内容")
ElseIf cmbField3.Text = "" Then
MsgBox("请输入字段名")
ElseIf cmbOperation3.Text = "" Then
MsgBox("请输入操作符")
ElseIf txtContent3.Text = "" Then
MsgBox("请输入要查询的内容")
End If
End If '给实体层传参
Dim enGroupQuery As New Model.GroupQueryM
enGroupQuery._field1 = GetDBName(cmbField1.Text.Trim())
enGroupQuery._field2 = GetDBName(cmbField2.Text.Trim())
enGroupQuery._field3 = GetDBName(cmbField3.Text.Trim())
enGroupQuery._operate1 = cmbOperation1.Text.Trim()
enGroupQuery._operate2 = cmbOperation2.Text.Trim()
enGroupQuery._operate3 = cmbOperation3.Text.Trim()
enGroupQuery._content1 = txtContent1.Text.Trim()
enGroupQuery._content2 = txtContent2.Text.Trim()
enGroupQuery._content3 = txtContent3.Text.Trim()
enGroupQuery._relation1 = GetDBName(cmbRelation1.Text.Trim())
enGroupQuery._relation2 = GetDBName(cmbRelation2.Text.Trim())
enGroupQuery.GetTable = GetTable() '通过函数的返回值给参数赋值 '给B层GroupQuery方法传递参数
Dim FGroupQuery As New Facade.GroupQuertFA
Dim table As DataTable
table = FGroupQuery.GroupQuery(enGroupQuery) If table.Rows.Count = 0 Then
MsgBox("没有记录,请重新设置查询条件", vbOKOnly, vbExclamation)
DataGridView1.DataSource = Nothing
Else
DataGridView1.DataSource = FGroupQuery.GroupQuery(enGroupQuery)
End If
End Sub ' 定义虚函数GetDBName,获取不同数据库的字段名
Protected Overridable Function GetDBName(ByVal control As String) As String
Return ""
End Function ' 定义虚函数GetDBName,获取不同数据库的表名
Protected Overridable Function GetTable() As String
Return ""
End Function
Private Sub Button2_Click_1(sender As Object, e As EventArgs) Handles btnExit.Click
Me.Close()
End Sub '组合关系一不为空后,显示第二行查询条件
Private Sub cmbRelation1_SelectedIndexChanged(sender As Object, e As EventArgs) Handles cmbRelation1.SelectedIndexChanged
cmbField2.Enabled = True
cmbOperation2.Enabled = True
cmbRelation2.Enabled = True
txtContent2.Enabled = True
End Sub '组合关系二不为空后,显示第三行查询条件
Private Sub cmbRelation2_SelectedIndexChanged(sender As Object, e As EventArgs) Handles cmbRelation2.SelectedIndexChanged
cmbField3.Enabled = True
cmbOperation3.Enabled = True
txtContent3.Enabled = True
End Sub End Class</span>



2,在B层,对D层数据库的查询结果做出处理

<span style="font-size:18px;">Imports Charge.IDAL
Imports Charge.Model
Public Class GroupQueryBLL
''' <summary>
''' 根据组合查询D层的返回结果,判断是否有值
''' </summary>
''' <param name="enGroupQuery"></param>
''' <returns>没有值,不返回任何东西,有,就返回信息</returns>
''' <remarks></remarks>
Public Function GroupQueryStudent(ByVal enGroupQuery As Model.GroupQueryM) As DataTable
Dim factory As New Factory.CreateFactory
Dim IGroupQuery As IGroupQuery = factory.CreateGroupQuery
Dim table As DataTable = IGroupQuery.GroupQuery(enGroupQuery) '检查D层返回的数据表中是否有数据
If table.Rows.Count = 0 Then
Return Nothing
Else
Return table
End If
End Function
End Class</span>

3,在D层对数据进行查询

<span style="font-size:18px;">/**********************************************
'类名:SQLGroupQuery
'命名空间:ChargeDAL
'创建时间:2015/1/5 20:58:39
'创建人:HXX
'修改时间:
'修改人:
'版本号:4.0.30319.18449
'说明:实现组合条件的
'版权:HHX
'/**********************************************
Imports System.Data.SqlClient
Imports System.Data
Imports Charge Public Class SQLGroupQuery : Implements IDAL.IGroupQuery ''' <summary>
''' 根据设置的条件,进行信息查询
''' </summary>
''' <param name="enGroupQuery"></param>
''' <returns>返回查询结果信息的集合</returns>
Public Function GroupQuery(enGroupQuery As Model.GroupQueryM) As DataTable Implements IDAL.IGroupQuery.GroupQuery
Dim strSQL As String = "QueryGroup" '调用存储过程 Dim prams As SqlParameter() = {New SqlParameter("@cmbField1", enGroupQuery._field1),
New SqlParameter("@cmbField2", enGroupQuery._field2),
New SqlParameter("@cmbField3", enGroupQuery._field3),
New SqlParameter("@cmbOperation1", enGroupQuery._operate1),
New SqlParameter("@cmbOperation2", enGroupQuery._operate2),
New SqlParameter("@cmbOperation3", enGroupQuery._operate3),
New SqlParameter("@txtContent1", enGroupQuery._content1),
New SqlParameter("@txtContent2", enGroupQuery._content2),
New SqlParameter("@txtContent3", enGroupQuery._content3),
New SqlParameter("@cmbRelation1", enGroupQuery._relation1),
New SqlParameter("@cmbRelation2", enGroupQuery._relation2),
New SqlParameter("@tableName", enGroupQuery.GetTable)} '设置参数
Dim MyHelper As New SqlHelper
Dim table As New DataTable
table = MyHelper.ExecSelect(strSQL, CommandType.StoredProcedure, prams)
Return table
End Function
End Class</span>

三、在继承窗体中的应用



在继承窗体中,需要重写模板父窗体中的方法,关键点有:字段的转换,数据表的返回。

<span style="font-size:18px;">  Private Sub FrmOperateWorkLog_Activated(sender As Object, e As EventArgs) Handles Me.Activated
'避免一个窗体多次打开,或者打开多个操作窗体
Dim frm As Form
'遍历打开了的每一个窗体
For Each frm In Application.OpenForms
'如果当前窗体不是主窗体或者没有被打开过
If frm.Name <> Me.Name And frm.Name <> FrmMain.Name And frm.Name <> FrmLine.Name Then
'其他打开的窗体最小化
frm.WindowState = 1
End If
Next
End Sub
Private Sub FrmMaintainInfo_Load(sender As Object, e As EventArgs) Handles MyBase.Load
'给字段赋值
cmbField1.Items.AddRange({"教师", "注册日期", "注册时间", "注销日期", "注销时间", "机器名"})
cmbField2.Items.AddRange({"教师", "注册日期", "注册时间", "注销日期", "注销时间", "机器名"})
cmbField3.Items.AddRange({"教师", "注册日期", "注册时间", "注销日期", "注销时间", "机器名"})
cmbOperation1.Items.AddRange({"=", "<", ">", "<>"})
cmbOperation2.Items.AddRange({"=", "<", ">", "<>"})
cmbOperation3.Items.AddRange({"=", "<", ">", "<>"})
cmbRelation1.Items.AddRange({"与", "或"})
cmbRelation2.Items.AddRange({"与", "或"})
End Sub
'重写获得表名方法
Protected Overrides Function GetTable() As String
enGroupQuery.GetTable = "TC_WorkLogInfo"
Return enGroupQuery.GetTable()
End Function
'重写转换成数据库字段方法
Protected Overrides Function GetDBName(control As String) As String
Select Case (control)
Case "教师"
Return "UserID"
Case "注册时间"
Return "OnTime"
Case "注册日期"
Return "OnDate"
Case "注销时间"
Return "OffTime"
Case "注销日期"
Return "OffDate"
Case "机器名"
Return "Computer"
Case "或"
Return "or"
Case "与"
Return "and"
Case Else
Return ""
End Select
End Function
End Class
</span>

到这里,利用窗体继承和模板方法进行组合查询就算是实现了。



四、应用说明

1,这里的返回类型都是DataTable,如果将其换为List,则就没有这么简单了。还需要多写一步(存储过程中),就像返回查询表格的参数一样,将查询表格的参数写到List中的表。

2,这里D层的查询是通过调用的存储过程,对存储过程的使用和理解,将在下一篇博客中详细说明。不过,在这里可以替换成一种类型,就像是第一次做机房时那样。例(第一次机房中):

<span style="font-size:18px;">txtSQL = txtSQL & tiaojian(Trim(cobozd1(0).Text)) & Trim(cobocz1(0).Text) & "'" & Trim(txtnr1.Text) & "'" _
& " and " _
& tiaojian(Trim(cobozd1(1).Text)) & Trim(cobocz1(1).Text) & " '" & Trim(txtnr2.Text) & "'" _
& " and " _
& tiaojian(Trim(cobozd1(2).Text)) & Trim(cobocz1(2).Text) & " '" & Trim(txtnr3.Text) & "'"</span>

在这里,也可以将存储过程,换成一般的文本类型查询。因为是应用的参数赋值,使用字符拼接的方式,将组合查询的三个情况看做是一种情况,也是可行的。



五、个人感想



学以致用,学了还要会用才行。刚开始学了设计模式的时候,真的感受不大。但用上了之后,真的觉得很方便。只是在用的过程中有点艰难,不过,把一个个的问题解决了,最后实现了,感觉真的很良好。

.NET重构(四):窗体继承+模板方法,完美实现组合查询的更多相关文章

  1. Javascript的四种继承方式

    在Javascript中,所有开发者定义的类都可以作为基类,但出于安全性考虑,本地类和宿主类不能作为基类,这样可以防止公用访问编译过的浏览器级的代码,因为这些代码可以被用于恶意攻击. 选定基类后,就可 ...

  2. vb.net之窗体继承

    相信很多自己动手敲过完整程序的同学都会发现,其实我们敲的很多窗体布局都非常的相似,有的部分用到的控件甚至一模一样,如果每一个窗体都自己重新摆放或者复制粘贴虽然没有问题,但是有时候若是修改其中一小点位置 ...

  3. windows窗体继承问题

    窗体继承什么时候用的到呢?当我们使用三层架构来编写我们的cs程序时,我们的U层大部分是windows窗体.这个时候如果我们有一些公共变量,或者是一个窗体需要使用另一个窗体的数据.或者是有一些用于判断的 ...

  4. WinForm窗体继承

    在Windows应用程序中,从现有的窗体继承,查看子窗体的设计视图时,会出现错误: 服务容器中已存在服务 System.Windows.Forms.Design.IEventHandlerServic ...

  5. WinForm窗体继承自定义的模板窗体出错

    在开发Winform程序的时候,我们往往需要根据需要做一些自定义的控件模块,这样可以给系统模块重复利用,或者实现更好的效果等功能.而今天自定义一个窗体,然后子窗体继承的时候出现了一点问题. 问题: 在 ...

  6. Java 面向对象(四)继承

    一.继承的概述(Inherited) 1.由来 多个类中存在相同属性和行为时,将这些内容抽取到单独一个类中,那么多个类无需再定义这些属性和行为,只要继承那个类即可. 其中,多个类可以称为 子类(派生类 ...

  7. Scala快速入门(四)——继承、接口

    Scala快速入门(四)--继承.接口 一.继承 1.继承的概念:省略 2.模板: class Person(n:String,a:Int) { var name:String=n var age:I ...

  8. 面向对象编程(四)继承,概念及super关键字,final关键字,Object类常见方法

    继承 概念: ①   继承背后的思想就是基于已存在的类来构建新类; ②   当从已存在类继承时,就重用了它的方法和属性,还可以添加新的方法和属性来定制新类以应对需求; ③   当从其它类导出的类叫作子 ...

  9. 一篇文章理解JS继承——原型链/构造函数/组合/原型式/寄生式/寄生组合/Class extends

    说实在话,以前我只需要知道"寄生组合继承"是最好的,有个祖传代码模版用就行.最近因为一些事情,几个星期以来一直心心念念想整理出来.本文以<JavaScript高级程序设计&g ...

随机推荐

  1. Java设计模式之单例模式 - Singleton

    用来创建独一无二的,是能有一个实例的对象的入场券.告诉你一个好消息,单例模式的类图可以说是所有模式的类图中最简单的,事实上,它的类图上只有一个类!但是,可不要兴奋过头,尽管从类设计的视角来说很简单,但 ...

  2. iOS 循环引用解决方案

    一.BLOCK 循环引用 一般表现为,某个类将block作为自己的属性变量,然后该类在block的方法体里面又使用了该类本身.构成循环引用. // 定义 block 的时候,会对外部变量做一次 cop ...

  3. mysql> set sql_mode='no_auto_value_on_zero';

    mysql> set sql_mode='no_auto_value_on_zero';

  4. 抽象常量class

    需要把经常用到的常量抽象到一个类里面管理 如:

  5. Unity之脚本编译顺序

    根据官方的解释,它们的编译顺序如下: (1)所有在Standard Assets.Pro Standard Assets或者Plugins文件夹中的脚本会产生一个Assembly-CSharp-fil ...

  6. python在d盘,robotframework引入seleniumlibrary报错

    在*** setting*** 中引入库   Library  SeleniumLibrary  报错 unknown seleniumlibrary library ,try to use quic ...

  7. 使用prelu

    一个使用方式:http://blog.csdn.net/xg123321123/article/details/52610919 还有一种是像relu那样写,我就是采用的这种方式,直接把名字从relu ...

  8. js函数式编程(三)-compose和pointFree

    compose即函数嵌套组合 组合compose在第一篇已经初见端倪,可以感受一下.compose函数的实现用闭包的方法.不完善实现如下: const compose = (f, g) => { ...

  9. centos6 安装windows字体

    注意:字体文件必须是TTF或者ttf格式的文件, 1.yum install -y fontconfig mkfontscale2.mkdir -p /usr/share/fonts/windows_ ...

  10. 如何用纯 CSS 创作一个菱形 loader 动画

    效果预览 在线演示 按下右侧的"点击预览"按钮可以在当前页面预览,点击链接可以全屏预览. https://codepen.io/comehope/pen/eKzjqK 可交互视频教 ...