C#机房重构之组合查询

版权声明:本文为博主原创文章,未经博主允许不得转载。 https://blog.csdn.net/Aran_WDX/article/details/81738575

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

  首先我们来了解一下什么是‘组合查询’,所谓查询我们都知道,就是通过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各位大佬多多指点。

猜你喜欢

转载自blog.csdn.net/Aran_WDX/article/details/81738575