C#机房重构之组合查询

  经过重重困难终于把机房重构的三大难点之一的组合查询给解决了,今天小编和大家分享一下组合查询过程中的难点和需要注意的地方。

  首先我们来了解一下什么是‘组合查询’,所谓查询我们都知道,就是通过sql语句通过DAL层传递的参数查找数据并返回。这是简单的查询,而组合查询的意思就如字面所知,将我要查询的条件组合起来,组合成我们需求的查询语句再去查询。

  至此,我们可以了解到这里的难点包括(条件的组合,sql语句的拼接),接下来我们就一点一点的解决问题,循环渐进。

  首先我们要做的就是完成多种条件的拼接,我们通过虚方法的重写,来转换数据库字段,把我们在UI层得到的string类型数据转换成我们想要的数据库的字段,用模版方法写好父模版,所有的其他组合查询都继承子窗体,重写虚方法发,添加各自不同的字段。

///父窗体代码

namespace UI
{
    public partial class frmGroupFind : Form
    {
        public frmGroupFind()
        {
            InitializeComponent();
        }
        Entity.GroupFind enGroupFind = new Entity.GroupFind();//实例化实体
        private void frmMdiStuInfo_Load(object sender, EventArgs e)
        {
            // TODO: 这行代码将数据加载到表“jiFangChongGouDataSet2.Student_Info”中。您可以根据需要移动或删除它。
            //this.student_InfoTableAdapter.Fill(this.jiFangChongGouDataSet2.Student_Info);
            #region//操作符

            CmbMark1.Items.Add(">");
            CmbMark1.Items.Add("<");
            CmbMark1.Items.Add("=");
            CmbMark1.Items.Add("<>");
            CmbMark2.Items.Add(">");
            CmbMark2.Items.Add("<");
            CmbMark2.Items.Add("=");
            CmbMark2.Items.Add("<>");
            CmbMark3.Items.Add(">");
            CmbMark3.Items.Add("<");
            CmbMark3.Items.Add("=");
            CmbMark3.Items.Add("<>");

            #endregion

            #region//关系符号
            
            CmbRelation1.Items.Add("与");
            CmbRelation1.Items.Add("或");

            
            CmbRelation2.Items.Add("与");
            CmbRelation2.Items.Add("或");
            #endregion

            #region//设置控件不可用状态
            CmbMark2.Enabled = false;
            CmbMark3.Enabled = false;
            
            CmbName2.Enabled = false;
            CmbName3.Enabled = false;

            CmbRelation2.Enabled = false;
            txtInfo2.Enabled = false;
            txtInfo3.Enabled = false;
            
            dtp1.Visible = false;
            dtp2.Visible = false;
            dtp3.Visible = false;
            #endregion

            #region//设置复选框只可以选择不可以输入
            this.CmbMark1.DropDownStyle = ComboBoxStyle.DropDownList;
            this.CmbMark2.DropDownStyle = ComboBoxStyle.DropDownList;
            this.CmbMark3.DropDownStyle = ComboBoxStyle.DropDownList;

            this.CmbName1.DropDownStyle = ComboBoxStyle.DropDownList;
            this.CmbName2.DropDownStyle = ComboBoxStyle.DropDownList;
            this.CmbName3.DropDownStyle = ComboBoxStyle.DropDownList;

            this.CmbRelation1.DropDownStyle = ComboBoxStyle.DropDownList;
            this.CmbRelation2.DropDownStyle = ComboBoxStyle.DropDownList;
            #endregion
        }
        #region//自己构造的虚方法
        public virtual string ToName(string combo)//将字段转化为数据库字段
        {
            return "";
        }

        protected virtual string Getdbtable()//获得数据库名称
        {
            return "";
        }

        protected virtual void ToDgv(Entity.GroupFind enGroupFind)//显示数据
        { 
            
        }
       #endregion

        private void btnSearch_Click(object sender, EventArgs e)
        {
            //主要完成输入内容的转换和拼接
            //判空
            if (CmbRelation1.Text=="")
            {
                if (CmbName1.Text == "" || CmbMark1.Text == "" || txtInfo1.Text == "")
                {
                    MessageBox.Show("第一行查询条件为空,请添加条件");
                }
            }
            if (CmbRelation1.Text!="")
            {
                 if (CmbName1.Text==""||CmbMark1.Text==""||txtInfo1.Text==""||CmbName2.Text==""||CmbMark2.Text==""||txtInfo2.Text=="")
                {
                    MessageBox.Show("输入的查询条件为空,请添加条件");
                }
            }

            if (CmbRelation2.Text!="")
            {
                if (CmbName1.Text==""||CmbMark1.Text==""||txtInfo1.Text==""||CmbName2.Text==""||CmbMark2.Text==""||txtInfo2.Text==""||CmbName3.Text == "" || CmbMark3.Text == "" || txtInfo3.Text == "")
                {
                    MessageBox.Show("输入的查询条件为空,请添加条件"); 
                }
            }

            //给实体赋值
            enGroupFind.CmbName1 = ToName(CmbName1.Text.Trim());
            enGroupFind.CmbName2 = ToName(CmbName2.Text.Trim());
            enGroupFind.CmbName3 = ToName(CmbName3.Text.Trim());

            enGroupFind.CmbOper1 = CmbMark1.Text.Trim();
            enGroupFind.CmbOper2 = CmbMark2.Text.Trim();
            enGroupFind.CmbOper3 = CmbMark3.Text.Trim();

            enGroupFind.CmbGroup1 = ToName(CmbRelation1.Text.Trim());
            enGroupFind.CmbGroup2 = ToName(CmbRelation2.Text.Trim());

            enGroupFind.txtInfo1 = txtInfo1.Text.Trim();
            enGroupFind.txtInfo2 = txtInfo2.Text.Trim();
            enGroupFind.txtInfo3 = txtInfo3.Text.Trim();

            enGroupFind.GetDataTable = Getdbtable();//从数据库中获取表格(选择调用那个数据库)

            
            Facade.GroupFindFacade groupFind = new Facade.GroupFindFacade();//实例化传参
            DataTable result = new DataTable();
            result = groupFind.GroupCheck(enGroupFind);//接收返回值
            if (result.Rows.Count == 0)//没有查询到
            {
                MessageBox.Show("没有复合条件的记录,请重新选择条件");
            }
            else
            {
                ToDgv(enGroupFind);//查询到以后调用子窗体中重写的方法显示数据
            }

        }

        private void CmbRelation1_SelectedIndexChanged(object sender, EventArgs e)
        {
            if (CmbRelation1.Text!="")//第一和组合条件不为空
           
            {
                CmbName2.Enabled = true;
                CmbMark2.Enabled = true;
                txtInfo2.Enabled = true;
                
            }

        }

        private void CmbRelation2_SelectedIndexChanged(object sender, EventArgs e)
        {
            if (CmbRelation2.Text!="")
            {
                CmbName3.Enabled = true;
                CmbMark3.Enabled = true;
                txtInfo3.Enabled = true;  
            }
            
        }

        private void btnClear_Click(object sender, EventArgs e)
        {
            this.Close();
        }

        private void fillByToolStripButton_Click(object sender, EventArgs e)
        {
            try
            {
                this.student_InfoTableAdapter.FillBy(this.jiFangChongGouDataSet2.Student_Info);
            }
            catch (System.Exception ex)
            {
                System.Windows.Forms.MessageBox.Show(ex.Message);
            }

        }

    }

所谓模版方法就是,写好一个模版,在其他地方需要用的类似的东西,直接继承,然后有需要的方法重写,其他公共的则继承

如何创建继承窗体呢?

//子窗体

public partial class OperatorDroupFind : UI.frmGroupFind
    {
        public OperatorDroupFind()
        {
            InitializeComponent();
        }
       
        public override string ToName(string combo)//重写虚方法,将自己要的字段转化成数据库字段
        {
            switch (combo)
            {
                case "卡号":
                    return "cardNo";
                case "学号":
                    return "StudentNo";
                case "姓名":
                    return "StudentName";
                case "性别":
                    return "Sex";
                case "专业":
                    return "Department";
                case"与":
                    return "and";
                case"或":
                    return "or";

                default:
                    return "";


            }
        }
        protected override string Getdbtable() //Select语句需求的数据库
        {
            return "Student_Info";
        }

        protected override void ToDgv(Entity.GroupFind enGroupFind)//重写方法,显示结果
        {
            dataGridView1.DataSource = "";
            DataTable dt = new DataTable();
            Facade.GroupFindFacade gf = new Facade.GroupFindFacade();//去拿到数据库的数据
            dt = gf.GroupCheck(enGroupFind);
            if (dt.Rows.Count==0)
            {
                MessageBox.Show("没有记录,请重新查询");
            }
            else
            {
                //子类中的需要的东西,父窗体只负责显示
                dataGridView1.DataSource = dt;
                dataGridView1.Refresh();
            }
           

        }
        private void CmbMark1_SelectedIndexChanged(object sender, EventArgs e)
        {

        }

        private void CmbName1_SelectedIndexChanged(object sender, EventArgs e)
        {

        }

        private void btnSearch_Click(object sender, EventArgs e)
        {
            给实体传值
            //Entity.GroupFind enGroupFind = new Entity.GroupFind()
            //{
            //    CmbName1 = ToName(CmbName1.Text),
            //    CmbName2 = ToName(CmbName2.Text),
            //    CmbName3 = ToName(CmbName3.Text),
            //    CmbOper1 = CmbMark1.Text.Trim(),
            //    CmbOper2 =CmbMark2.Text.Trim(),
            //    CmbOper3 = CmbMark3.Text.Trim(),
            //    CmbGroup1 = ToName(CmbRelation1.Text),
            //    CmbGroup2 = ToName(CmbRelation2.Text),
            //    txtInfo1 = txtInfo1.Text.Trim(),
            //    txtInfo2 = txtInfo2.Text.Trim(),
            //    txtInfo3 = txtInfo3.Text.Trim(),

            //    GetDataTable = Getdbtable()//从数据库中获取表格
            //};
            //Facade.GroupFindFacade groupfind = new Facade.GroupFindFacade();
            //DataTable result = new DataTable();
            //result = groupfind.GroupCheck(enGroupFind);


        }

        private void OperatorDroupFind_Load(object sender, EventArgs e)
        {
            this.Text = "学生信息";
            CmbName1.Items.Add("卡号");
            CmbName1.Items.Add("学号");
            CmbName1.Items.Add("姓名");
            CmbName1.Items.Add("性别");
            CmbName1.Items.Add("专业");


            CmbName2.Items.Add("卡号");
            CmbName2.Items.Add("学号");
            CmbName2.Items.Add("姓名");
            CmbName2.Items.Add("性别");
            CmbName2.Items.Add("专业");

            CmbName3.Items.Add("卡号");
            CmbName3.Items.Add("学号");
            CmbName3.Items.Add("姓名");
            CmbName3.Items.Add("性别");
            CmbName3.Items.Add("专业");
        }
    }

我们上面解决了如何把字段转化成数据库字段,也在DAL层完成了传参,接下来就是我们的存储过程了。

 

第二个问题,我们要将sql语句拼凑成我们想要的,在这我们还是借助存储过程。接下来我们一起来看看,存储过程的思路和要注意的点。

//存储过程

USE [JiFangChongGou]
GO
/****** Object:  StoredProcedure [dbo].[PROC_GroupFind]    Script Date: 08/16/2018 11:22:14 ******/
SET ANSI_NULLS ON
GO
SET QUOTED_IDENTIFIER ON
GO
-- =============================================
-- Author:		<Author,,王东兴
-- Create date: <Create Date,,>
-- Description:	<组合查询>
-- =============================================
ALTER PROCEDURE [dbo].[PROC_GroupFind]
	-- Add the parameters for the stored procedure here
	@CmbName1 varchar(50),
	@CmbName2 varchar(50),
	@CmbName3 varchar(50),
	@CmbOper1 varChar(10),
	@CmbOper2 varChar(10),
	@CmbOper3 varChar(10),
	@CmbGroup1 varchar(50),
	@CmbGroup2 varchar(50),
	@GetDataTable varchar(50),
	@txtInfo1 varchar(50),
	@txtInfo2 varchar(50),
	@txtInfo3 varchar(50)
AS
	declare @TempSql varchar(500)--临时存放Sql语句
BEGIN
	-- SET NOCOUNT ON added to prevent extra result sets from
	-- interfering with SELECT statements.
		SET @TempSql='Select * from '+@GetDataTable+' Where'+CHAR(32)+@CmbName1+@CmbOper1 +CHAR(39)+@txtInfo1 +CHAR(39)
	if (@CmbGroup1!='')
	BEGIN
		SET @TempSql =@TempSql +CHAR(32) +@CmbGroup1 +CHAR(32)+@CmbName2 +@CmbOper2 +CHAR(39)+@txtInfo2 +CHAR(39)
		if (@CmbGroup2!='')
		begin
		SET @TempSql =@TempSql +CHAR(32)+@CmbGroup2 +CHAR(32)+@CmbName3 +@CmbOper3 +CHAR(39)+@txtInfo3 +CHAR(39)
	end

    END
    exec(@TempSql)
END

存储过程中最重要的就是sql语句的拼接,当然在这里也有许多没注意到的东西,下面我们来一起来看一看

首先我们看我们需要不同的几种条件所以我们xi先定义一个@Tempsql来存储

SET @TempSql='Select * from '+@GetDataTable+' Where'+CHAR(32)+@CmbName1+@CmbOper1 +CHAR(39)+@txtInfo1 +CHAR(39)

看这一行代码,第一个要注意的地方在于'from'的右边和'WHERE'的左边必须要添加空格,如果不加空格会报一些类似于找不到ca参数的错误。

第二点要注意的地方:

SET @TempSql =@TempSql +CHAR(32) +@CmbGroup1 +CHAR(32)+@CmbName2 +@CmbOper2 +CHAR(39)+@txtInfo2 +CHAR(39)

我们看到其中有CHAR(32)+参数,其实在这里把他们两个看做了一个整体,我们需要连接整体的时候在(+CHAR(32)+参数)的前面加入空格。

以至于具体为什么这样可以自己去了解一下sql语句。今天组合查询的分享就到此结束了,本人C#小白,如果有什么问题,还希望ge各位大佬多多指点。

  • 0
    点赞
  • 1
    收藏
    觉得还不错? 一键收藏
  • 23
    评论
特别说明 -------- 新版本请访问网站www.bluefishes.net. 考虑到稳定性,新版本不支持Visual Studio.NET 2002. 产品名称 -------- SharpRefactor(C#代码重构工具) 产品简述 -------- 本工具用于代码重构和代码自动生成。现阶段主要用于C#代码重构。 所谓重构也就是“保持软件的外在功能不变,重新调整其内部结构”。 关于每种重构模式的含义,请参见http://www.refactoring.com/ 具体功能参见具体版本的特性列表。 对重构很感兴趣或是很关注使用效率的用户,希望[使用指南]一节对你有所助益。 版本 ---- 1.0.0(BETA). 发布日期 -------- 2003/6/13 作者 ---- C# Refactor Team. 制作 ---- Blue Workshop. 环境要求 -------- Visual Studio.Net 2003 Windows 2000 + SP2 + SMTP Service 特别提示 -------------- 本插件使用了异常处理和报告机制。 一般而言,环境、代码以及其他原因都会导致程序出错。因此,在您使用本插件的过程中,可能会弹出错误报告。一部分错误不会影响使用,另一部分会影响使用。 C# Refactor Team愿意随时提供技术支持,及时为你解除问题。 版本1.0.0特性 ------------- Rename Parameter Rename Local Variable Rename Field Rename Property Rename Class Rename NameSpace Safe Delete Parameter Safe Delete Local Variable Safe Delete Field Safe Delete Property Safe Delete Method Safe Delete Class Safe Delete NameSpace Extract Interface Undo/Redo Preview usage before refactor(重构前预览) Auto build after refactor(重构后自动生成) Options(工具选项) User feedback(用户反馈) 使用指南 -------- 所有功能暂不支持静态成员。 尽量使用鼠标右键菜单。 尽量使用快捷方式,比如:单击鼠标右键,弹出菜单后再连续按‘R’键和‘C’键就可以调用[Rename]菜单下的[Rename Class]命令。 在使用Rename系列命令时,需要先转到定义代码元素的地方。此时,可以先使用右键菜单中的[转到定义]命令。 在Option中可以设置首选项。 由于Visual Studio在生成较大的解决方案时有时会不成功,所以Auto build after refactor通常用于较小的解决方案。 Rename NameSpace与Move Class不同。Move Class的焦点在Class,即改变类所在的NameSpace。而Rename NameSpace的焦点在NameSpace,即改变指定NameSpace的名字,并更新该NameSpace的所有引用(Usages)。 错误报告以及建议功能需要网络连接和Windows自带的SMTP服务。因为发送速度很快,所以不会占用您宝贵的时间。 可以使用User feedback功能提出您睿智的建议、批评、任何意见。 技术支持 -------- Tiger.BlueWorkshop@163.net 下载 ---- www.csdn.net 版本 发布日期 ----------------------------- 1.0.0(Beta) 2003/6/13
评论 23
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值