.NET重构(四):窗体继承+模板方法,完美实现组合查询
导读:在机房重构中,有好些个查询都是大同小异,最为显著的就是组合查询了。怎样给自己省事儿,相同的东西能不能重复利用,就成了一个现实的问题。第一遍做机房的时候,使用的更多的是:复制+粘贴。学习了设计模式后,可以用模板方法解决。这篇文章,就通过窗体继承和模板方法,实现组合查询。
观点:组合查询在机房中有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重构(四):窗体继承+模板方法,完美实现组合查询的更多相关文章
- Javascript的四种继承方式
在Javascript中,所有开发者定义的类都可以作为基类,但出于安全性考虑,本地类和宿主类不能作为基类,这样可以防止公用访问编译过的浏览器级的代码,因为这些代码可以被用于恶意攻击. 选定基类后,就可 ...
- vb.net之窗体继承
相信很多自己动手敲过完整程序的同学都会发现,其实我们敲的很多窗体布局都非常的相似,有的部分用到的控件甚至一模一样,如果每一个窗体都自己重新摆放或者复制粘贴虽然没有问题,但是有时候若是修改其中一小点位置 ...
- windows窗体继承问题
窗体继承什么时候用的到呢?当我们使用三层架构来编写我们的cs程序时,我们的U层大部分是windows窗体.这个时候如果我们有一些公共变量,或者是一个窗体需要使用另一个窗体的数据.或者是有一些用于判断的 ...
- WinForm窗体继承
在Windows应用程序中,从现有的窗体继承,查看子窗体的设计视图时,会出现错误: 服务容器中已存在服务 System.Windows.Forms.Design.IEventHandlerServic ...
- WinForm窗体继承自定义的模板窗体出错
在开发Winform程序的时候,我们往往需要根据需要做一些自定义的控件模块,这样可以给系统模块重复利用,或者实现更好的效果等功能.而今天自定义一个窗体,然后子窗体继承的时候出现了一点问题. 问题: 在 ...
- Java 面向对象(四)继承
一.继承的概述(Inherited) 1.由来 多个类中存在相同属性和行为时,将这些内容抽取到单独一个类中,那么多个类无需再定义这些属性和行为,只要继承那个类即可. 其中,多个类可以称为 子类(派生类 ...
- Scala快速入门(四)——继承、接口
Scala快速入门(四)--继承.接口 一.继承 1.继承的概念:省略 2.模板: class Person(n:String,a:Int) { var name:String=n var age:I ...
- 面向对象编程(四)继承,概念及super关键字,final关键字,Object类常见方法
继承 概念: ① 继承背后的思想就是基于已存在的类来构建新类; ② 当从已存在类继承时,就重用了它的方法和属性,还可以添加新的方法和属性来定制新类以应对需求; ③ 当从其它类导出的类叫作子 ...
- 一篇文章理解JS继承——原型链/构造函数/组合/原型式/寄生式/寄生组合/Class extends
说实在话,以前我只需要知道"寄生组合继承"是最好的,有个祖传代码模版用就行.最近因为一些事情,几个星期以来一直心心念念想整理出来.本文以<JavaScript高级程序设计&g ...
随机推荐
- 关于Pre-bound JDBC Connection found! HibernateTransactionManager does not 异常小结
昨天帮女朋友配置ssh框架的多数据源, 本以为对此已经很熟悉,配置完其他的错倒是还能接受,调了一下就好了. 唯独 Pre-bound JDBC Connection found! Hibernate ...
- HTML中实现Table表头点击升序/降序排序
题目:如下图,请实现表格信息的排序功能,当点击表头的属性区域,将表格信息进行排序切换功能,即第一次点击为降序排序,再一次点击进行升序排序. 姓名 力量 敏捷 智力 德鲁伊王 17 24 13 月之骑士 ...
- CF1081E Missing Numbers
思路: 贪心乱搞. 实现: #include <bits/stdc++.h> using namespace std; typedef long long ll; const ll m = ...
- 【数据分析 R语言实战】学习笔记 第八章 方差分析与R实现
方差分析泛应用于商业.经济.医学.农业等诸多领域的数量分析研究中.例如商业广告宣传方面,广告效果可能会受广告式.地区规模.播放时段.播放频率等多个因素的影响,通过方差分析研究众多因素中,哪些是主要的以 ...
- Selenium私房菜系列5 -- 第一个Selenium RC测试案例
<Selenium简介>中讲过,Selenium RC支持多种语言编写测试案例,如:C#,Python.在工作中,我倾向于是用Python这类动态语言编写测试案例,因为这样的测试案例无需编 ...
- ActiveAndroid问题no such table解决总结
android.database.sqlite.SQLiteException: no such table at android.database.sqlite.SQLiteConnection ...
- 关键字: on
关键字: on 数据库在通过连接两张或多张表来返回记录时,都会生成一张中间的临时表,然后再将这张临时表返回给用户. 在使用left jion时,on和where条件的区别如下: 1. on条件是在生成 ...
- 使用Google Colab训练神经网络(二)
Colaboratory 是一个 Google 研究项目,旨在帮助传播机器学习培训和研究成果.它是一个 Jupyter 笔记本环境,不需要进行任何设置就可以使用,并且完全在云端运行.Colaborat ...
- WPF知识点全攻略05- XAML内容控件
此处简单列举出布局控件外,其他常用的控件: Window:WPF窗口 UserControl:用户控件 Page:页 Frame:用来浏览Page页 Border:嵌套控件,提供边框和背景. Butt ...
- 【转】SpringBoot 2.0.0新版和SpringBoot1.5.2版本中Tomcat配置的差别
https://blog.csdn.net/wd2014610/article/details/79587161 2018年春SpringBoot 2.0.0 新版本有了很多新的改变,其中Tomcat ...