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

观点:组合查询在机房中有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. P1216 [USACO1.5]数字三角形 Number Triangles

    题目描述 观察下面的数字金字塔. 写一个程序来查找从最高点到底部任意处结束的路径,使路径经过数字的和最大.每一步可以走到左下方的点也可以到达右下方的点. 7 3 8 8 1 0 2 7 4 4 4 5 ...

  2. OAuth2.0基本原理及应用

    OAuth2.0基本原理及应用 一.OAuth是一个关于授权(authorization)的开放网络标准,在全世界得到广泛应用,目前的版本是2.0版. 在详细讲解OAuth 2.0之前,需要了解几个专 ...

  3. 分布式系统中的CAP原理和BASE理论

    CAP是一致性(Consistency).可用性(Availability).分区容忍性(Partition tolerance)的缩写.CAP原理指的是这三个要素最多只能同时实现两点,不可能三者兼顾 ...

  4. VC操作WORD文档总结

    一.写在开头 最近研究word文档的解析技术,我本身是VC的忠实用户,看到C#里面操作WORD这么舒服,同时也看到单位有一些需求,就想尝试一下,结果没想到里面的技术点真不少,同时网络上的共享资料很多, ...

  5. 通过90行代码学会HTML5 WebSQL的4种基本操作

    Web SQL数据库API是一个独立的规范,在浏览器层面提供了本地对结构化数据的存储,已经被很多现代浏览器支持了. 我们通过一个简单的例子来了解下如何使用Web SQL API在浏览器端创建数据库表并 ...

  6. 闭包和OC的block的本质

    “闭包” 一词来源于以下两者的结合:要执行的代码块(由于自由变量被包含在代码块中,这些自由变量以及它们引用的对象没有被释放)和为自由变量提供绑定的计算环境(作用域). http://blog.csdn ...

  7. Java Miniui实现批量上传文件demo 201906221520

    可能需要的jar包: 需要miniui(类似easyui). Test2019062201.jsp <%@ page language="java" contentType= ...

  8. 快学UiAutomator创建第一个实例

    工具准备 一.准备好java环境(JDK)和安卓环境(SDK.ADT)jdk1.6+ \eclipse\SDK \ADT详情百度,安装java环境 二.打开eclipse 三.创建步骤: 右键新建== ...

  9. House of force

    0x00 利用要点 1.申请一块非常大的块. 2.精心构造size覆盖top chunk的chunk header. 3.调用malloc()实现任意地址写 0x01 申请一块非常大的块. 申请一个负 ...

  10. lucene4.10.2实例(增删改查)

    最新jar和src免费下载:http://download.csdn.net/detail/u011518709/8248403 lucene 包的组成结构:对于外部应用来说索引模块(index)和检 ...