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

观点:组合查询在机房中有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. PHP-PHPExcel用法详解

    以下文章来源:diandian_520 http://blog.csdn.net/diandian_520/article/details/7827038 1.header header(" ...

  2. 新萝卜家园GHOST WIN7系统3专业装机版

    系统来自系统妈:http://www.xitongma.com/ 系统概述 萝卜家园GHOST win7 64位装机旗舰版加快“网上邻居”共享速度:取消不需要的网络服务组件,系统支持Windows安装 ...

  3. codevs 1992 聚会

    时间限制: 1 s  空间限制: 128000 KB  题目等级 : 黄金 Gold 题目描述 Description 小S 想要从某地出发去同学k的家中参加一个party,但要有去有回.他想让所用的 ...

  4. 使用python模拟cookie登陆wooyun

    import urllib2 class SimpleCookieHandler(urllib2.BaseHandler): def http_request(self, req): simple_c ...

  5. Grid Infrastructure 启动的五大问题 (文档 ID 1526147.1)

    适用于: Oracle Database - Enterprise Edition - 版本 11.2.0.1 和更高版本本文档所含信息适用于所有平台 用途 本文档的目的是总结可能阻止 Grid In ...

  6. 几个不错的APP网站。

    http://www.yunshipei.com/yunshipei.html http://www.appcan.cn/

  7. 剑指offer——把字符串转换成整数(c++)

    题目描述请你写一个函数StrToInt,实现把字符串转换成整数这个功能.当然,不能使用atoi或者其他类似的库函数. 示例 1:输入: " -42"输出: -42解释: 第一个非空 ...

  8. 安装vc++6.0的步骤

    我们学习计算机,就必须要先将编程的c语言学好,打好基础,学习c语言最好的方法就是多上机联系,对于联系我们需要在自己的电脑上安装vc++6.0来进行平日里的联系.1.打开电脑进行联网,打开浏览器搜索vc ...

  9. java在线聊天项目 客户端登陆窗口LoginDialog的注册用户功能 修改注册逻辑 增空用户名密码的反馈 增加showMessageDialog()提示框

    LoginDialog类的代码修改如下: package com.swift.frame; import java.awt.EventQueue; import java.awt.event.Acti ...

  10. ios retain copy 以及copy协议

    阅读本文之前首先了解Copy与Retain的区别: Copy是创建一个新对象,Retain是创建一个指针,引用对象计数加1. Copy属性表示两个对象内容相同,新的对象retain为1 ,与旧有对象的 ...