您的位置:首页 > 其它

【机房重构】-组合查询之模版模式

2017-06-25 20:56 330 查看
机房重构中,组合查询也是一个让人头疼的难点,其实说难也只是因为自己没有理清头绪,没有开始。如果自己理清了关系,并着手开始,然后一点一点攻克,最后当功能实现,代码顺利跑起来的那一刻,会觉得其实一不过如此,哈哈。所以,总结两个字,去做!

一、基本介绍

本着机房重构实践模式的原则,组合查询用到了模版模式。

模板模式属于行为型模式,其意图是定义一个操作的算法骨架,而将一些步骤延迟到子类中,可以不改变一个算法的结构即可以重新定义概算法的某些特定步骤。

直白的理解,模版模式就是先准备一个模子,然后需要做的只是把原料倒到模子里,再加工加工就ok了,这样就省去了很多重复的过程,放到代码里说,就是实现了复用,减少了代码的重复。

二、具体实现

1、建立模版父窗体



以上是制作的一个模版父窗体,即添加一个windows窗体,设计模版界面,然后在模版窗体里写抽象出来的类和方法的代码。

UI层代码

public partial class OpGFa : Form
{
public OpGFa()
{
InitializeComponent();
}

Entity.GroupInquiryEntity groupentity = new Entity.GroupInquiryEntity();
public void OpGFa_Load(object sender, EventArgs e)
{
//将参数传递给实体,赋初值
//因为不同的窗体字段不同,所以赋空,子窗体重写
groupentity.fileds1 = "";
groupentity.fileds2 = "";
groupentity.fileds3 = "";

//操作符
cmboperator1.Items.Add(">");
cmboperator1.Items.Add("<");
cmboperator1.Items.Add("=");
cmboperator1.Items.Add("<>");

cmboperator2.Items.Add(">");
cmboperator2.Items.Add("<");
cmboperator2.Items.Add("=");
cmboperator2.Items.Add("<>");

cmboperator3.Items.Add(">");
cmboperator3.Items.Add("<");
cmboperator3.Items.Add("=");
cmboperator3.Items.Add("<>");

//关系
cmbrelation1.Items.Add("");
cmbrelation1.Items.Add("与");
cmbrelation1.Items.Add("或");

cmbrelation2.Items.Add("");
cmbrelation2.Items.Add("与");
cmbrelation2.Items.Add("或");

//窗体加载后,后两组控件默认不可用
cmbfields2.Enabled = false;
cmbfields3.Enabled = false;
cmboperator2.Enabled = false;
cmboperator3.Enabled = false;
cmbrelation2.Enabled = false;
txtInquiry2.Enabled = false;
txtInquiry3.Enabled = false;
}
//优化控件可用性
//组合关系1不为空后,显示第二行查询条件
public void cmbrelation1_SelectedIndexChanged(object sender, EventArgs e)
{
if (cmbrelation1.Text == "")
{
cmbfields2.Enabled = false;
cmbfields3.Enabled = false;
cmboperator2.Enabled = false;
cmboperator3.Enabled = false;
cmbrelation2.Enabled = false;
txtInquiry2.Enabled = false;
txtInquiry3.Enabled = false;
}
else
{
cmbfields2.Enabled = true;
cmboperator2.Enabled = true;
cmbrelation2.Enabled = true;
txtInquiry2.Enabled = true;
}
}
//组合关系2不为空后,显示第三行查询条件
public void cmbrelation2_SelectedIndexChanged(object sender, EventArgs e)
{
if (cmbrelation2.Text == "")
{
cmbfields3.Enabled = false;
cmboperator3.Enabled = false;
txtInquiry3.Enabled = false;
}
else
{
cmbfields3.Enabled = true;
cmboperator3.Enabled = true;
txtInquiry3.Enabled = true;
}
}

public void btnOK_Click(object sender, EventArgs e)
{
//第一行组合关系为空
if (cmbrelation1.Text == "")
{
if (cmbfields1.Text == ""||cmboperator1.Text == "" ||txtInquiry1.Text == "" )
{
MessageBox.Show("第一行查询条件不能为空,请完善查询信息!");
}
}
//当第一个组合关系不为空时
if (cmbrelation1.Text != "")
{
if (cmbfields1.Text == ""||cmboperator1.Text == "" ||txtInquiry1.Text == "" || cmbfields2.Text == ""||cmboperator2.Text == "" ||txtInquiry2.Text == "")
{
MessageBox.Show("前两行信息不能为空,请完善查询信息!");
}
}
//当第二个组合关系不为空,则判断所有文本框是否为空
if (cmbrelation2.Text != "")
{
if (cmbfields1.Text == ""||cmboperator1.Text == "" ||txtInquiry1.Text == "" || cmbfields2.Text == ""||cmboperator2.Text == "" ||txtInquiry2.Text == ""||cmbfields3.Text == ""||cmboperator3.Text == "" ||txtInquiry3.Text == "")
{
MessageBox.Show("信息不能为空,请完善查询信息!");
}
}

//将参数传递给实体
groupentity.fileds1 = ToName(cmbfields1.Text);
groupentity.fileds2 = ToName(cmbfields2.Text);
groupentity.fileds3 = ToName(cmbfields3.Text);

groupentity.operator1 = cmboperator1.Text;
groupentity.operator2 = cmboperator2.Text;
groupentity.operator3 = cmboperator3.Text;

groupentity.context1 = txtInquiry1.Text;
groupentity.context2 = txtInquiry2.Text;
groupentity.context3 = txtInquiry2.Text;

groupentity.relation1 = ToName(cmbrelation1.Text);
groupentity.relation2 = ToName(cmbrelation2.Text);

groupentity.tableName = GetTable();

//实例化外观,将查询到的数据表显示到控件中
Facade.OpFacade facade = new Facade.OpFacade();
DataTable table = facade.groupInquiry(groupentity);
if (table.Rows.Count > 0)
{
dataGridView1.DataSource = table;
}
else
{
MessageBox.Show("没有记录,请重新设计查询条件");
}
}

//模版方法
//定义虚函数ToName,将查询的内容转换成数据库的列名称
public virtual string ToName(string combo)
{
return "";
}
//获得数据库名称
public virtual string GetTable()
{
return "";
}
//把表显示到datagrideview中
protected virtual void Todgv()
{

}

//关闭该窗体
private void btnExit_Click(object sender, EventArgs e)
{
this.Close();
}
}

D层代码

//组合查询
public DataTable groupInquiry(Entity.GroupInquiryEntity groupentity)
{
SqlHelper.sqlhelper sqlhelper = new SqlHelper.sqlhelper();
SqlParameter[] sqlparams = {
new SqlParameter("@fileds1",groupentity.fileds1),
new SqlParameter("@fileds2",groupentity.fileds2),
new SqlParameter("@fileds3",groupentity.fileds3),
new SqlParameter("@operator1",groupentity.operator1),
new SqlParameter("@operator2",groupentity.operator2),
new SqlParameter("@operator3",groupentity.operator3),
new SqlParameter("@context1",groupentity.context1),
new SqlParameter("@context2",groupentity.context2),
new SqlParameter("@context3",groupentity.context3),
new SqlParameter("@relation1",groupentity.relation1),
new SqlParameter("@relation2",groupentity.relation2),
new SqlParameter("@tableName",groupentity.tableName)
};
string sql = "PROC_GroupInquiry";
DataTable table = SqlHelper.sqlhelper.GetDataTable(sql, CommandType.StoredProcedure, sqlparams);
return table;
}
有D层代码可知我用到了存储过程,来实现复杂的查询,存储过程如下:

-- =============================================
-- Author:		吕德彪
-- Create date: 2017/6/10
-- Description:	组合查询
-- =============================================
ALTER PROCEDURE [dbo].[PROC_GroupInquiry]
-- Add the parameters for the stored procedure here
@fileds1 varchar(10),
@fileds2 varchar(10),
@fileds3 varchar(10),
@operator1 varchar(10),
@operator2 varchar(10),
@operator3 varchar(10),
@context1 varchar(10),
@context2 varchar(10),
@context3 varchar(10),
@relation1 varchar(10),
@relation2 varchar(10),
@tableName varchar(20)
AS
declare @TempSql varchar(500)--临时存放sql语句
BEGIN
SET @TempSql='SELECT * FROM '+@tableName +' WHERE ' +@fileds1 +@operator1+char(39) + @context1 + char(39)
if (@relation1 != '')
BEGIN
SET @TempSql=@TempSql+@relation1+CHAR(32)+@fileds2 +@operator2+CHAR(39)+@context2+CHAR(39)
if (@relation2 != '')
BEGIN
SET @TempSql=@TempSql+@relation2+CHAR(32)+@fileds3+@operator3+CHAR(39)+@context3+CHAR(39)
END
END
EXECUTE(@TempSql)
END


2、建立子窗体



如上图建立子窗体,选择继承创建的父窗体模板,然后就可以得到一模一样的子窗体了。通过在子窗体里重写一些方法和类,以实现不同的功能就可以了。

实现工作记录查询的代码如下:

public partial class OpGWorkRecord : LoginUI.OpGFa
{
public OpGWorkRecord()
{
InitializeComponent();
}

private void OpGWorkRecord_Load(object sender, EventArgs e)
{
string[] fileName2 = { "教师",  "登录日期", "登录时间", "注销日期", "注销时间", "机器名", "状态" };
cmbfields1.Items.AddRange(fileName2);
cmbfields2.Items.AddRange(fileName2);
cmbfields3.Items.AddRange(fileName2);
}

public override string ToName(string combo)
{
switch (combo)
{
case "教师":
return "UserID";
case "登录日期":
return "loginDate";
case "登录时间":
return "loginTime";
case "注销日期":
return "logoutDate";
case "注销时间":
return "logoutTime";
case "机器名":
return "computer";
case "状态":
return "status";

case "或":
return "or";
case "与":
return "and";
default:
return "";
}
}

//返回数据库
public override string GetTable()
{
return "WorkLog_Info";
}
}


三、总结

刚开始做确实无从下手,但是只要开始了,慢慢摸索,慢慢实践,整个过程就会慢慢的变得越来越完善,Just To Do!
内容来自用户分享和网络整理,不保证内容的准确性,如有侵权内容,可联系管理员处理 点击这里给我发消息