欢迎您访问程序员文章站本站旨在为大家提供分享程序员计算机编程知识!
您现在的位置是: 首页  >  IT编程

C#通用查询器

程序员文章站 2022-05-03 12:47:14
很多通用查询器,对查询条件中的AND及OR的支持度不是很好,要么全部是AND要么全部是OR。笔者通过一段时间的摸索,终于完成了一个自己较为满意的通用查询器, 可以实现多条件的AND及OR,现将实现过程记录一下: 1、在App.config中添加数据库连接字符串。

    很多通用查询器,对查询条件中的and及or的支持度不是很好,要么全部是and要么全部是or。笔者通过一段时间的摸索,终于完成了一个自己较为满意的通用查询器,

可以实现多条件的and及or,现将实现过程记录一下:

    1、在app.config中添加数据库连接字符串。

    <connectionstrings>
        <add name ="connstring" connectionstring="server=.;database=db_test;uid=sa;pwd=********;"/>
    </connectionstrings>

    2、添加一个数据库操作帮助类,命名为dbhelper。

    /// <summary>
    /// sql数据库访问类
    /// </summary>
    public static class dbhelper
    {
        private static sqlconnection conn = null;

        /// <summary>
        /// 连接对象
        /// </summary>
        public static sqlconnection connection
        {
            get
            {
                string connstring = configurationmanager.connectionstrings["connstring"].connectionstring;
                if (conn == null)
                {
                    try
                    {
                        conn = new sqlconnection(connstring);
                    }
                    catch (exception) { throw; }
                }
                return conn;
            }
        }

        /// <summary>
        /// 打开数据库连接
        /// </summary>
        public static void open()
        {
            if (conn.state != connectionstate.open)
            {
                conn.open();
            }
        }

        /// <summary>
        /// 关闭数据库连接
        /// </summary>
        public static void close()
        {
            if (conn.state == connectionstate.open)
            {
                conn.close();
            }
        }

        /// <summary>
        /// 创建一个新的命令对象
        /// </summary>
        /// <param name="commandtext">要执行的sql语句或存储过程名称</param>
        /// <param name="commandtype">commandtype枚举值,表示执行sql语句还是存储过程。</param>
        /// <param name="parameters">参数数组</param>
        private static sqlcommand createcommand(string commandtext, commandtype commandtype, params sqlparameter[] parameters)
        {
            try
            {
                using (sqlcommand cmd = new sqlcommand())
                {
                    cmd.commandtext = commandtext;
                    cmd.commandtype = commandtype;
                    cmd.connection = connection;
                    if (parameters != null)
                    {
                        foreach (sqlparameter param in parameters)
                        {
                            cmd.parameters.add(param);
                        }
                    }
                    return cmd;
                }
            }
            catch (exception) { throw; }
        }

        /// <summary>
        /// 执行sql命令,并输出影响的行数。
        /// </summary>
        /// <param name="commandtext">要执行的sql语句或存储过程名称</param>
        /// <param name="commandtype">commandtype枚举值,表示执行sql语句还是存储过程。</param>
        /// <param name="parameters">参数数组</param>
        /// <return>返回影响的行数</return>
        public static int runcommand(string commandtext, commandtype commandtype, params sqlparameter[] parameters)
        {
            try
            {
                using (sqlcommand cmd = createcommand(commandtext, commandtype, parameters))
                {
                    open();
                    int rows = cmd.executenonquery();
                    cmd.parameters.clear();
                    close();
                    return rows;
                }
            }
            catch (exception) { throw; }
        }

        /// <summary>
        /// 执行增删改的方法
        /// </summary>
        /// <param name="commandtext">要执行的sql语句或存储过程名称</param>
        /// <param name="commandtype">commandtype枚举值,表示执行sql语句还是存储过程。</param>
        /// <param name="parameters">参数数组</param>
        /// <returns>成功返回true</returns>
        public static bool save(string commandtext, commandtype commandtype, params sqlparameter[] parameters)
        {
            try
            {
                using (sqlcommand cmd = createcommand(commandtext, commandtype, parameters))
                {
                    open();
                    int n = cmd.executenonquery();
                    cmd.parameters.clear();
                    close();
                    if (n > 0)
                        return true;
                    else
                        return false;
                }
            }
            catch (exception) { throw; }
        }

        /// <summary>
        /// 执行增删改的方法
        /// </summary>
        /// <param name="commandtext">要执行的sql语句</param>
        /// <param name="parameters">参数数组</param>
        /// <returns>成功返回true</returns>
        public static bool save(string commandtext, params sqlparameter[] parameters)
        {
            try
            {
                return save(commandtext, commandtype.text, parameters);
            }
            catch (exception) { throw; }
        }

        /// <summary>
        /// 获得datatable
        /// </summary> 
        /// <param name="commandtext">要执行的sql语句或存储过程名称</param>
        /// <param name="commandtype">commandtype枚举值,表示执行sql语句还是存储过程。</param>
        /// <param name="parameters">参数数组</param>
        /// <returns></returns>
        public static datatable gettable(string commandtext, commandtype commandtype, params  sqlparameter[] parameters)
        {
            try
            {
                using (sqlcommand cmd = createcommand(commandtext, commandtype, parameters))
                {
                    sqldataadapter da = new sqldataadapter
                    {
                        selectcommand = cmd
                    };
                    datatable dt = new datatable();
                    da.fill(dt);
                    cmd.parameters.clear();
                    close();
                    return dt;
                }
            }
            catch (exception) { throw; }
        }

        /// <summary>
        /// 获得datatable
        /// </summary> 
        /// <param name="commandtext">要执行的sql语句或存储过程名称</param>
        /// <param name="parameters">参数数组</param>
        /// <returns></returns>
        public static datatable gettable(string commandtext,  params  sqlparameter[] parameters)
        {
            try
            {
                return gettable(commandtext,commandtype.text,parameters);
            }
            catch (exception) { throw; }
        }

        /// <summary>
        /// 获得datatable
        /// </summary> 
        /// <param name="commandtext">要执行的sql语句</param>
        /// <returns></returns>
        public static datatable gettable(string commandtext)
        {
            return gettable(commandtext, commandtype.text, null);
        }

        /// <summary>
        /// 获得sqldatareader
        /// </summary> 
        /// <param name="commandtext">要执行的sql语句或存储过程名称</param>
        /// <param name="commandtype">commandtype枚举值,表示执行sql语句还是存储过程。</param>
        /// <param name="parameters">参数数组</param>
        /// <returns></returns>
        public static sqldatareader getreader(string commandtext, commandtype commandtype, params  sqlparameter[] parameters)
        {
            try
            {
                using (sqlcommand cmd = createcommand(commandtext, commandtype, parameters))
                {
                    open();
                    return cmd.executereader();
                }
            }
            catch (exception) { throw; }
        }

        /// <summary>
        /// 获得sqldatareader
        /// </summary>
        /// <param name="commandtext">要执行的sql语句或存储过程名称</param>
        /// <param name="parameters">参数数组</param>
        /// <returns></returns>
        public static sqldatareader getreader(string commandtext, params  sqlparameter[] parameters)
        {
            return getreader(commandtext, commandtype.text, parameters);
        }

        /// <summary>
        /// 获得sqldatareader
        /// </summary>
        /// <param name="commandtext">要执行的sql语句或存储过程名称</param>
        /// <param name="commandtype">commandtype枚举值,表示执行sql语句还是存储过程。</param>
        /// <returns></returns>
        public static sqldatareader getreader(string commandtext, commandtype commandtype)
        {
            return getreader(commandtext, commandtype, null);
        }

        /// <summary>
        /// 获得sqldatareader
        /// </summary>
        /// <param name="commandtext">要执行的sql语句或存储过程名称</param>
        /// <returns></returns>
        public static sqldatareader getreader(string commandtext)
        {
            return getreader(commandtext, commandtype.text, null);
        }

        /// <summary>
        /// 执行sql命令,并返回一个值。
        /// </summary> 
        /// <param name="commandtext">要执行的sql语句或存储过程名称</param>
        /// <param name="commandtype">commandtype枚举值,表示执行sql语句还是存储过程。</param>
        /// <param name="parameters">参数数组</param>
        /// <returns></returns>
        public static object getscalar(string commandtext, commandtype commandtype, params  sqlparameter[] parameters)
        {
            object obj = null;
            try
            {
                using (sqlcommand cmd = createcommand(commandtext, commandtype, parameters))
                {
                    open();
                    obj = cmd.executescalar();
                    cmd.parameters.clear();
                    close();
                    return obj;
                }
            }
            catch (exception) { throw; }
        }

        /// <summary>
        /// 执行sql命令,并返回一个值。
        /// </summary> 
        /// <param name="commandtext">要执行的sql语句或存储过程名称</param>
        /// <param name="parameters">参数数组</param>
        /// <returns></returns>
        public static object getscalar(string commandtext, params  sqlparameter[] parameters)
        {
            return getscalar(commandtext, commandtype.text, parameters);
        }

        /// <summary>
        /// 执行sql命令,并返回一个值。
        /// </summary> 
        /// <param name="commandtext">要执行的sql语句或存储过程名称</param>
        /// <param name="commandtype">commandtype枚举值,表示执行sql语句还是存储过程。</param>
        /// <returns></returns>
        public static object getscalar(string commandtext, commandtype commandtype)
        {
            return getscalar(commandtext, commandtype, null);
        }

        /// <summary>
        /// 执行sql命令,并返回一个值。
        /// </summary> 
        /// <returns></returns>
        public static object getscalar(string commandtext)
        {
            return getscalar(commandtext, commandtype.text, null);
        }
    }

    3、添加一个数据类型转换类,命名为sqldbtypehelper。

        /// <summary>
        /// sqldbtype转换为c#数据类型
        /// </summary>
        /// <param name="sqldbtype"></param>
        /// <returns></returns>
        public static type sqldbtypetocsharptype(sqldbtype sqldbtype)
        {
            switch (sqldbtype)
            {
                case sqldbtype.bigint:
                    return typeof(int64);
                case sqldbtype.binary:
                    return typeof(object);
                case sqldbtype.bit:
                    return typeof(boolean);
                case sqldbtype.char:
                    return typeof(string);
                case sqldbtype.datetime:
                    return typeof(datetime);
                case sqldbtype.decimal:
                    return typeof(decimal);
                case sqldbtype.float:
                    return typeof(double);
                case sqldbtype.image:
                    return typeof(object);
                case sqldbtype.int:
                    return typeof(int32);
                case sqldbtype.money:
                    return typeof(decimal);
                case sqldbtype.nchar:
                    return typeof(string);
                case sqldbtype.ntext:
                    return typeof(string);
                case sqldbtype.nvarchar:
                    return typeof(string);
                case sqldbtype.real:
                    return typeof(single);
                case sqldbtype.smalldatetime:
                    return typeof(datetime);
                case sqldbtype.smallint:
                    return typeof(int16);
                case sqldbtype.smallmoney:
                    return typeof(decimal);
                case sqldbtype.text:
                    return typeof(string);
                case sqldbtype.timestamp:
                    return typeof(object);
                case sqldbtype.tinyint:
                    return typeof(byte);
                case sqldbtype.udt://自定义的数据类型
                    return typeof(object);
                case sqldbtype.uniqueidentifier:
                    return typeof(object);
                case sqldbtype.varbinary:
                    return typeof(object);
                case sqldbtype.varchar:
                    return typeof(string);
                case sqldbtype.variant:
                    return typeof(object);
                case sqldbtype.xml:
                    return typeof(object);
                default:
                    return null;
            }
        }

        /// <summary>
        /// sql server数据类型转换为sqldbtype类型
        /// </summary>
        /// <param name="sqltypestring"></param>
        /// <returns></returns>
        public static sqldbtype sqltypestringtosqldbtype(string sqltypestring)
        {
            sqldbtype dbtype = sqldbtype.variant;   //默认为object

            switch (sqltypestring)
            {
                case "int":
                    dbtype = sqldbtype.int;
                    break;
                case "varchar":
                    dbtype = sqldbtype.varchar;
                    break;
                case "bit":
                    dbtype = sqldbtype.bit;
                    break;
                case "datetime":
                    dbtype = sqldbtype.datetime;
                    break;
                case "decimal":
                    dbtype = sqldbtype.decimal;
                    break;
                case "float":
                    dbtype = sqldbtype.float;
                    break;
                case "image":
                    dbtype = sqldbtype.image;
                    break;
                case "money":
                    dbtype = sqldbtype.money;
                    break;
                case "ntext":
                    dbtype = sqldbtype.ntext;
                    break;
                case "nvarchar":
                    dbtype = sqldbtype.nvarchar;
                    break;
                case "smalldatetime":
                    dbtype = sqldbtype.smalldatetime;
                    break;
                case "smallint":
                    dbtype = sqldbtype.smallint;
                    break;
                case "text":
                    dbtype = sqldbtype.text;
                    break;
                case "bigint":
                    dbtype = sqldbtype.bigint;
                    break;
                case "binary":
                    dbtype = sqldbtype.binary;
                    break;
                case "char":
                    dbtype = sqldbtype.char;
                    break;
                case "nchar":
                    dbtype = sqldbtype.nchar;
                    break;
                case "numeric":
                    dbtype = sqldbtype.decimal;
                    break;
                case "real":
                    dbtype = sqldbtype.real;
                    break;
                case "smallmoney":
                    dbtype = sqldbtype.smallmoney;
                    break;
                case "sql_variant":
                    dbtype = sqldbtype.variant;
                    break;
                case "timestamp":
                    dbtype = sqldbtype.timestamp;
                    break;
                case "tinyint":
                    dbtype = sqldbtype.tinyint;
                    break;
                case "uniqueidentifier":
                    dbtype = sqldbtype.uniqueidentifier;
                    break;
                case "varbinary":
                    dbtype = sqldbtype.varbinary;
                    break;
                case "xml":
                    dbtype = sqldbtype.xml;
                    break;
            }
            return dbtype;
        }

    4、添加一个自定义控件,命名为:conditioncontrol。

C#通用查询器

    注:底下的是panel1,上面的控件名分别为:cmbleft1、cmbfieldtext1、cmboperator1、txtvalue1、cmbright1、cmbrelation1、btnadd、btnremove。

    5、conditioncontrol的代码实现:

    public partial class conditioncontrol : usercontrol
    {
        #region 字段
        private int conditioncount = 1;     //panel个数
        private int panelspace = 2;         //panel间隔
        private string[] tempfieldnames, tempfieldtypes, tempfieldtexts;
        private control temptargetcontrol;  //添加conditioncontrol控件承载控件
        #endregion

        #region 属性
        //字段名
        public string[] fieldnames
        {
            get
            {
                return tempfieldnames;
            }
            set
            {
                if (value != null)
                {
                    tempfieldnames = new string[value.length];
                    array.copy(value, tempfieldnames, value.length);
                }
            }
        }
        //字段数据类型
        public string[] fieldtypes
        {
            get
            {
                return tempfieldtypes;
            }
            set
            {
                if (value != null)
                {
                    tempfieldtypes = new string[value.length];
                    array.copy(value, tempfieldtypes, value.length);
                }
            }
        }
        //字段文本
        public string[] fieldtexts
        {
            get
            {
                return tempfieldtexts;
            }
            set
            {
                if (value != null)
                {
                    tempfieldtexts = new string[value.length];
                    array.copy(value, tempfieldtexts, value.length);
                }
            }
        }
        //要处理的控件
        public control targetcontrol
        {
            get
            {
                return temptargetcontrol;
            }
            set
            {
                if (value != null)
                {
                    temptargetcontrol = value;
                }
            }
        }
        #endregion

        #region 构造函数
        /// <summary>
        /// 构造函数
        /// </summary>
        public conditioncontrol()
        {
            initializecomponent();
        }
        #endregion

        #region 设置其它下拉框数据源
        /// <summary>
        /// 设置左括号下拉框数据源
        /// </summary>
        /// <param name="combobox"></param>
        private void setleftdatasource(combobox combobox)
        {
            datatable dt = new datatable();
            dt.columns.add(new datacolumn("name"));
            dt.columns.add(new datacolumn("value"));

            datarow newrow = dt.newrow();
            newrow["name"] = "";
            newrow["value"] = "";
            dt.rows.add(newrow);
            newrow = dt.newrow();
            newrow["name"] = "(";
            newrow["value"] = "(";
            dt.rows.add(newrow);

            combobox.datasource = dt;
            combobox.displaymember = "name";
            combobox.valuemember = "value";
        }

        /// <summary>
        /// 设置字段文本下拉框数据源
        /// </summary>
        /// <param name="combobox"></param>
        private void setfieldtextdatasource(combobox combobox)
        {
            if (verifyfieldmatch())
            {
                combobox.items.addrange(tempfieldtexts);
            }
        }

        /// <summary>
        /// 设置右括号下拉框数据源
        /// </summary>
        /// <param name="combobox"></param>
        private void setrightdatasource(combobox combobox)
        {
            datatable dt = new datatable();
            dt.columns.add(new datacolumn("name"));
            dt.columns.add(new datacolumn("value"));

            datarow newrow = dt.newrow();
            newrow["name"] = "";
            newrow["value"] = "";
            dt.rows.add(newrow);
            newrow = dt.newrow();
            newrow["name"] = ")";
            newrow["value"] = ")";
            dt.rows.add(newrow);

            combobox.datasource = dt;
            combobox.displaymember = "name";
            combobox.valuemember = "value";
        }

        /// <summary>
        /// 设置关系符下拉框数据源
        /// </summary>
        /// <param name="combox"></param>
        private void setrelationdatasource(combobox combobox)
        {
            datatable dt = new datatable();

            dt.columns.add(new datacolumn("name"));
            dt.columns.add(new datacolumn("value"));

            datarow newrow = dt.newrow();
            newrow["name"] = "并且";
            newrow["value"] = "and";
            dt.rows.add(newrow);
            newrow = dt.newrow();
            newrow["name"] = "或者";
            newrow["value"] = "or";
            dt.rows.add(newrow);

            combobox.datasource = dt;
            combobox.displaymember = "name";
            combobox.valuemember = "value";
        }
        #endregion

        #region 初始化
        public void initialize()
        {
            if (verifyfieldmatch())
            {
                //左括号
                setleftdatasource(cmbleft1);
                //字段文本
                if (tempfieldtexts[0] == "")
                {
                    setfieldtextdatasource(cmbfieldtext1);
                }
                else
                {
                    //第一行设为""
                    list<string> listfieldname = tempfieldnames.tolist();
                    listfieldname.insert(0, "");
                    tempfieldnames = listfieldname.toarray();

                    list<string> listfieldtype = tempfieldtypes.tolist();
                    listfieldtype.insert(0, "");
                    tempfieldtypes = listfieldtype.toarray();

                    list<string> listfieldtext = tempfieldtexts.tolist();
                    listfieldtext.insert(0, "");
                    tempfieldtexts = listfieldtext.toarray();

                    setfieldtextdatasource(cmbfieldtext1);
                }
                //右括号
                setrightdatasource(cmbright1);
                //关系符
                setrelationdatasource(cmbrelation1);
            }
        }
        #endregion

        #region 验证字段是否匹配
        /// <summary>
        /// 验证字段是否匹配
        /// </summary>
        /// <returns>通过返回true</returns>
        public bool verifyfieldmatch()
        {
            if (tempfieldnames == null || tempfieldtypes == null || tempfieldtexts == null)
            {
                messagebox.show("字段的名称或数据类型或标题未赋值。", "提示", messageboxbuttons.ok, messageboxicon.information);
                return false;
            }
            else
            {
                if (tempfieldnames.length != tempfieldtypes.length || tempfieldnames.length != tempfieldtexts.length)
                {
                    messagebox.show("字段的名称或数据类型或标题长度不一致。", "提示", messageboxbuttons.ok, messageboxicon.information);
                    return false;
                }
            }
            return true;
        }
        #endregion

        #region 查找控件
        /// <summary>
        /// 查找panel
        /// </summary>
        /// <param name="panelname">panel名</param>
        /// <returns>返回panel</returns>
        private control findpanel(string panelname)
        {
            foreach (control ctrl in controls)
            {
                if (ctrl.name == panelname)
                {
                    return ctrl;
                }
            }
            return null;
        }

        /// <summary>
        /// 查找panel中指定的控件
        /// </summary>
        /// <param name="panelname">panel名</param>
        /// <param name="controlname">要找的控件名</param>
        /// <returns>返回控件</returns>
        private control findcontrol(string panelname, string controlname)
        {
            control panel = findpanel(panelname);
            if (panel != null)
            {
                foreach (control ctrl in panel.controls)
                {
                    if (ctrl.name == controlname)
                    {
                        return ctrl;
                    }
                }
            }
            return null;
        }
        #endregion

        #region 根据数据类型进行获取
        /// <summary>
        /// 根据数据类型返回其所属类型
        /// </summary>
        /// <param name="fieldtype">字段类型</param>
        /// <returns>所属类型</returns>
        private string getkindbyfieldtype(string fieldtype)
        {
            switch (fieldtype.tolower())
            {
                //值为""时返回""
                case "":
                    return "";
                //二进制类型,无运算符。
                case "binary":
                case "varbinary":
                case "image":
                    return null;
                //文本类型,可用(= like > >= < <= <>)运算符。
                case "char":
                case "nchar":
                case "varchar":
                case "nvarchar":
                case "text":
                case "ntext":
                    return "text";
                //数字、日期类型,只能用(= > >= < <= <>)运算符。
                case "datetime":
                case "smalldatetime":
                case "int":
                case "tinyint":
                case "smallint":
                case "bigint":
                case "float":
                case "money":
                case "smallmoney":
                case "real":
                case "decimal":
                case "numeric":
                    return "number";
                //bool类型,只能用(= <>)运算符。
                case "bit":
                    return "bool";
                default:
                    return null;
            }
        }

        /// <summary>
        /// 根据数据类型返回对应类型的字段值
        /// </summary>
        /// <param name="fieldtype">字段类型</param>
        /// <param name="value">字段值</param>
        /// <returns>对应类型的字段值</returns>
        private object getvaluebyfieldtype(string fieldtype, string value)
        {
            switch (fieldtype.tolower())
            {
                //值为""时返回""
                case "":
                    return "";
                //二进制类型
                case "binary":
                case "varbinary":
                case "image":
                    return null;
                //文本类型
                case "char":
                case "nchar":
                case "varchar":
                case "nvarchar":
                case "text":
                case "ntext":
                    return value;
                //日期类型
                case "datetime":
                case "smalldatetime":
                    return datetime.parse(value).toshortdatestring();
                //整型类型
                case "int":
                    return int.parse(value);
                case "tinyint":
                    return byte.parse(value);
                case "smallint":
                    return short.parse(value);
                case "bigint":
                    return long.parse(value);
                //单精度类型
                case "float":
                case "money":
                case "smallmoney":
                case "real":
                    return float.parse(value);
                //双精度类型
                case "decimal":
                case "numeric":
                    return double.parse(value);
                //bool类型
                case "bit":
                    return bool.parse(value);
                default:
                    return null;
            }
        }
        #endregion

        #region 设置运算符下拉框数据源
        /// <summary>
        /// 设置运算符下拉框数据源(文本类型)
        /// </summary>
        /// <param name="combox">来源下拉框</param>
        /// <param name="isempty">值是否为""</param>
        private void setoperatordatasourcefortext(combobox combox, bool isempty)
        {
            datatable dt = new datatable();
            dt.columns.add(new datacolumn("name"));
            dt.columns.add(new datacolumn("value"));

            if (isempty == true)
            {
                datarow rownew = dt.newrow();
                rownew["name"] = "";
                rownew["value"] = "";
                dt.rows.add(rownew);
            }
            else
            {
                datarow rownew = dt.newrow();
                rownew["name"] = "等于";
                rownew["value"] = "=";
                dt.rows.add(rownew);

                rownew = dt.newrow();
                rownew["name"] = "包含";
                rownew["value"] = "like";
                dt.rows.add(rownew);

                rownew = dt.newrow();
                rownew["name"] = "大于";
                rownew["value"] = ">";
                dt.rows.add(rownew);

                rownew = dt.newrow();
                rownew["name"] = "大于等于";
                rownew["value"] = ">=";
                dt.rows.add(rownew);

                rownew = dt.newrow();
                rownew["name"] = "小于";
                rownew["value"] = "<";
                dt.rows.add(rownew);

                rownew = dt.newrow();
                rownew["name"] = "小于等于";
                rownew["value"] = "<=";
                dt.rows.add(rownew);

                rownew = dt.newrow();
                rownew["name"] = "不等于";
                rownew["value"] = "<>";
                dt.rows.add(rownew);

                rownew = dt.newrow();
                rownew["name"] = "为null";
                rownew["value"] = "is null";
                dt.rows.add(rownew);

                rownew = dt.newrow();
                rownew["name"] = "不为null";
                rownew["value"] = "is not null";
                dt.rows.add(rownew);
            }

            combox.datasource = dt;
            combox.displaymember = "name";
            combox.valuemember = "value";
        }

        /// <summary>
        /// 设置运算符下拉框数据源(数字、日期类型)
        /// </summary>
        /// <param name="combox"></param>
        private void setoperatordatasourcefornumber(combobox combox)
        {
            datatable dt = new datatable();
            dt.columns.add(new datacolumn("name"));
            dt.columns.add(new datacolumn("value"));

            datarow rownew = dt.newrow();
            rownew["name"] = "等于";
            rownew["value"] = "=";
            dt.rows.add(rownew);

            rownew = dt.newrow();
            rownew["name"] = "大于";
            rownew["value"] = ">";
            dt.rows.add(rownew);

            rownew = dt.newrow();
            rownew["name"] = "大于等于";
            rownew["value"] = ">=";
            dt.rows.add(rownew);

            rownew = dt.newrow();
            rownew["name"] = "小于";
            rownew["value"] = "<";
            dt.rows.add(rownew);

            rownew = dt.newrow();
            rownew["name"] = "小于等于";
            rownew["value"] = "<=";
            dt.rows.add(rownew);

            rownew = dt.newrow();
            rownew["name"] = "不等于";
            rownew["value"] = "<>";
            dt.rows.add(rownew);

            combox.datasource = dt;
            combox.displaymember = "name";
            combox.valuemember = "value";
        }

        /// <summary>
        /// 设置运算符下拉框数据源(bool类型)
        /// </summary>
        /// <param name="combox"></param>
        private void setoperatordatasourceforbool(combobox combox)
        {
            datatable dt = new datatable();
            dt.columns.add(new datacolumn("name"));
            dt.columns.add(new datacolumn("value"));

            datarow rownew = dt.newrow();
            rownew["name"] = "等于";
            rownew["value"] = "=";
            dt.rows.add(rownew);

            rownew = dt.newrow();
            rownew["name"] = "不等于";
            rownew["value"] = "<>";
            dt.rows.add(rownew);

            combox.datasource = dt;
            combox.displaymember = "name";
            combox.valuemember = "value";
        }
        #endregion

        #region 字段文本选择改变时
        /// <summary>
        /// 字段文本选择改变时
        /// </summary>
        /// <param name="sender"></param>
        /// <param name="e"></param>
        private void cmbfieldtext_selectedindexchanged(object sender, eventargs e)
        {
            int index = -1;
            combobox cmbfieldtext = sender as combobox;
            if (cmbfieldtext != null)
            {
                index = cmbfieldtext.selectedindex;
            }
            if (index == -1)
            {
                return;
            }
            string i = cmbfieldtext.name.substring(12);
            string fieldtype = tempfieldtypes[index].tolower();
            combobox cmboperator = findcontrol("panel" + i, "cmboperator" + i) as combobox;

            //如果不是日期类型
            if (fieldtype != "datetime" && fieldtype != "smalldatetime")
            {
                control txtvalue = findcontrol("panel" + i, "txtvalue" + i);
                if (txtvalue != null)
                {
                    //如果是日期控件
                    if (txtvalue.gettype().name == "datetimepicker")
                    {
                        control paneli = findpanel("panel" + i);
                        if (paneli != null)
                        {
                            point point = txtvalue.location;
                            size size = new size(txtvalue.width, txtvalue.height);
                            paneli.controls.remove(txtvalue);
                            textbox txtvaluei = new textbox
                            {
                                name = "txtvalue" + i,
                                location = point,
                                size = size
                            };
                            paneli.controls.add(txtvaluei);
                        }
                    }
                    else
                    {
                        if (txtvalue.gettype().name == "textbox")
                        {
                            if (fieldtype == "")
                            {
                                txtvalue.text = "";
                            }
                        }
                    }
                }
            }
            switch (getkindbyfieldtype(fieldtype).tolower())
            {
                case "":
                    setoperatordatasourcefortext(cmboperator, true);
                    break;
                case "text":
                    setoperatordatasourcefortext(cmboperator, false);
                    break;
                case "number":
                    setoperatordatasourcefornumber(cmboperator);
                    //如果是日期类型
                    if (fieldtype == "datetime" || fieldtype == "smalldatetime")
                    {
                        control paneli = findpanel("panel" + i);
                        if (paneli != null)
                        {
                            control txtvaluei = findcontrol("panel" + i, "txtvalue" + i);
                            if (txtvaluei != null)
                            {
                                point point = txtvaluei.location;
                                size size = new size(txtvaluei.width, txtvaluei.height);
                                paneli.controls.remove(txtvaluei);
                                datetimepicker datetimepicker = new datetimepicker
                                {
                                    name = "txtvalue" + i,
                                    location = point,
                                    size = size,
                                    customformat = "yyyy-mm-dd",
                                    format = datetimepickerformat.custom
                                };
                                paneli.controls.add(datetimepicker);
                            }
                        }
                    }
                    break;
                case "bool":
                    setoperatordatasourceforbool(cmboperator);
                    break;
                default:
                    break;
            }
        }
        #endregion

        #region 加减按钮
        /// <summary>
        /// 加按钮
        /// </summary>
        /// <param name="sender"></param>
        /// <param name="e"></param>
        private void btnadd_click(object sender, eventargs e)
        {
            try
            {
                if (temptargetcontrol != null)
                {
                    //验证字段是否符合
                    if (!verifyfieldmatch())
                    {
                        return;
                    }
                    conditioncount++;

                    //panel
                    point pointpanel = new point(panel1.location.x, panel1.location.y + (panel1.height + panelspace) * (conditioncount - 1));
                    size sizepanel = new size(panel1.width, panel1.height);
                    panel paneli = new panel
                    {
                        name = "panel" + conditioncount.tostring(),
                        location = pointpanel,
                        size = sizepanel
                    };

                    //左括号
                    size sizeleft = new size(cmbleft1.width, cmbleft1.height);
                    combobox cmblefti = new combobox
                    {
                        formattingenabled = true,
                        name = "cmbleft" + conditioncount.tostring(),
                        size = sizeleft,
                        dropdownstyle = comboboxstyle.dropdownlist
                    };

                    //字段文本
                    size sizefieldtext = new size(cmbfieldtext1.width, cmbfieldtext1.height);
                    combobox cmbfieldtexti = new combobox
                    {
                        formattingenabled = true,
                        name = "cmbfieldtext" + conditioncount.tostring(),
                        size = sizefieldtext,
                        dropdownstyle = comboboxstyle.dropdownlist
                    };

                    //运算符
                    size sizeoperator = new size(cmboperator1.width, cmboperator1.height);
                    combobox cmboperatori = new combobox
                    {
                        formattingenabled = true,
                        name = "cmboperator" + conditioncount.tostring(),
                        size = sizeoperator,
                        dropdownstyle = comboboxstyle.dropdownlist
                    };

                    //文本
                    size sizevalue = new size(txtvalue1.width, txtvalue1.height);
                    textbox txtvaluei = new textbox
                    {
                        name = "txtvalue" + conditioncount.tostring(),
                        size = sizevalue
                    };

                    //右括号
                    size sizeright = new size(cmbright1.width, cmbright1.height);
                    combobox cmbrighti = new combobox
                    {
                        formattingenabled = true,
                        name = "cmbright" + conditioncount.tostring(),
                        size = sizeright,
                        dropdownstyle = comboboxstyle.dropdownlist
                    };

                    //关系符
                    size sizerelation = new size(cmbrelation1.width, cmbrelation1.height);
                    combobox cmbrelationi = new combobox
                    {
                        formattingenabled = true,
                        name = "cmbrelation" + conditioncount.tostring(),
                        size = sizerelation,
                        dropdownstyle = comboboxstyle.dropdownlist
                    };

                    //字段文本注册事件
                    cmbfieldtexti.selectedindexchanged += new eventhandler(cmbfieldtext_selectedindexchanged);

                    //设置数据源
                    setleftdatasource(cmblefti);
                    setfieldtextdatasource(cmbfieldtexti);
                    setrightdatasource(cmbrighti);
                    setrelationdatasource(cmbrelationi);

                    //将控件添加到paneli
                    paneli.controls.add(cmblefti);
                    cmblefti.left += cmbleft1.left;
                    cmblefti.top += cmbleft1.top;

                    paneli.controls.add(cmbfieldtexti);
                    cmbfieldtexti.left += cmbfieldtext1.left;
                    cmbfieldtexti.top += cmbfieldtext1.top;

                    paneli.controls.add(cmboperatori);
                    cmboperatori.left += cmboperator1.left;
                    cmboperatori.top += cmboperator1.top;

                    paneli.controls.add(txtvaluei);
                    txtvaluei.left += txtvalue1.left;
                    txtvaluei.top += txtvalue1.top;

                    paneli.controls.add(cmbrighti);
                    cmbrighti.left += cmbright1.left;
                    cmbrighti.top += cmbright1.top;

                    paneli.controls.add(cmbrelationi);
                    cmbrelationi.left += cmbrelation1.left;
                    cmbrelationi.top += cmbrelation1.top;

                    //添加paneli
                    controls.add(paneli);
                    height += panel1.height + panelspace;
                    temptargetcontrol.height += panel1.height + panelspace;
                }
            }
            catch (exception ex)
            {
                messagebox.show(ex.message, "提示", messageboxbuttons.ok, messageboxicon.information);
            }
        }

        /// <summary>
        /// 减按钮
        /// </summary>
        /// <param name="sender"></param>
        /// <param name="e"></param>
        private void btnremove_click(object sender, eventargs e)
        {
            if (temptargetcontrol != null)
            {
                if (conditioncount > 1)
                {
                    control paneli = findpanel("panel" + conditioncount.tostring());
                    if (paneli != null)
                    {
                        controls.remove(paneli);
                        height -= paneli.height + panelspace;
                        temptargetcontrol.height -= paneli.height + panelspace;
                        conditioncount--;
                    }
                }
            }
        }
        #endregion

        #region 获取where条件
        /// <summary>
        /// 获取where条件
        /// </summary>
        /// <param name="parameters"></param>
        /// <returns>where条件</returns>
        public string getwherecondition(out sqlparameter[] parameters)
        {
            parameters = null;

            //验证字段是否符合
            if (!verifyfieldmatch())
            {
                return string.empty;
            }

            //遍历产生where条件
            stringbuilder sbwhere = new stringbuilder();
            list<sqlparameter> lstparams = new list<sqlparameter>();
            int leftcount = 0, rightcount = 0;
            for (int i = 1; i <= conditioncount; i++)
            {
                //所选字段序号及文本
                int index = -1;
                string fieldtext = "";
                if (findcontrol("panel" + i, "cmbfieldtext" + i) is combobox cmbfieldtext)
                {
                    index = cmbfieldtext.selectedindex;
                    fieldtext = cmbfieldtext.text;
                }

                //左括号
                combobox cmbleft = findcontrol("panel" + i, "cmbleft" + i) as combobox;
                if (cmbleft != null)
                {
                    if (cmbleft.text != string.empty)
                    {
                        leftcount++;
                        if (i == 1)
                        {
                            sbwhere.append("(");
                        }
                        else
                        {
                            sbwhere.append(" " + "(");
                        }
                    }
                }

                //字段文本
                if (index != -1 && fieldtext != "")
                {
                    if ((cmbleft != null && cmbleft.text != string.empty) || i == 1)
                    {
                        sbwhere.append(tempfieldnames[index]);
                    }
                    else
                    {
                        sbwhere.append(" " + tempfieldnames[index]);
                    }
                }

                //运算符
                combobox cmboperator = null;
                if (index != -1 && fieldtext != "")
                {
                    cmboperator = findcontrol("panel" + i, "cmboperator" + i) as combobox;
                    if (cmboperator != null && cmboperator.selectedindex != -1)
                    {
                        sbwhere.append(" " + cmboperator.selectedvalue.tostring());
                    }
                }

                //文本值
                if (index != -1 && fieldtext != "")
                {
                    control txtvalue = findcontrol("panel" + i, "txtvalue" + i);
                    if (txtvalue != null)
                    {
                        string strkind = getkindbyfieldtype(tempfieldtypes[index]);
                        var strvalue = getvaluebyfieldtype(tempfieldtypes[index], txtvalue.text);

                        //sql参数化查询(防注入)
                        sqlparameter param = new sqlparameter
                        {
                            parametername = "@" + txtvalue.name,
                            sqldbtype = sqldbtypehelper.sqltypestringtosqldbtype(tempfieldtypes[index])
                        };
                        param.value = strvalue;
                        lstparams.add(param);

                        if (strkind == "text")
                        {
                            if (cmboperator != null)
                            {
                                switch (cmboperator.selectedvalue.tostring().toupper())
                                {
                                    case "like":
                                        sbwhere.append(" " + "'%'+" + "@" + txtvalue.name + "+'%'");
                                        break;
                                    case "is null":
                                        txtvalue.text = string.empty;
                                        break;
                                    case "is not null":
                                        txtvalue.text = string.empty;
                                        break;
                                    default:
                                        sbwhere.append(" " + "@" + txtvalue.name);
                                        break;
                                }
                            }
                        }
                        else
                        {
                            sbwhere.append(" " + "@" + txtvalue.name);
                        }
                    }
                }

                //右括号
                if (findcontrol("panel" + i, "cmbright" + i) is combobox cmbright && cmbright.text != string.empty)
                {
                    rightcount++;
                    if (rightcount > leftcount)
                    {
                        messagebox.show("左括号与右括号不匹配。", "提示", messageboxbuttons.ok, messageboxicon.information);
                        return string.empty;
                    }
                    sbwhere.append(")");
                }

                //关系符
                if (findcontrol("panel" + i, "cmbrelation" + i) is combobox cmbrelation)
                {
                    if (i < conditioncount)
                    {
                        sbwhere.append(" " + cmbrelation.selectedvalue.tostring());
                    }
                }
            }

            //括号匹配
            if (leftcount != rightcount)
            {
                messagebox.show("左括号与右括号不匹配。", "提示", messageboxbuttons.ok, messageboxicon.information);
                return string.empty;
            }

            //处理无效关键字及开头或末尾是and或or
            string strwhere = sbwhere.tostring().trim();

            dictionary<string, string> dictinvalid = new dictionary<string, string>();
            dictinvalid.add("()", "");
            dictinvalid.add("( ", "(");
            dictinvalid.add(" )", ")");
            dictinvalid.add("(and", "(");
            dictinvalid.add("(or", "(");
            dictinvalid.add("and)", ")");
            dictinvalid.add("or)", ")");
            dictinvalid.add("(and)", "");
            dictinvalid.add("(or)", "");
            dictinvalid.add("and and", "and");
            dictinvalid.add("and or", "and");
            dictinvalid.add("or and", "or");
            dictinvalid.add("or or", " or");
            dictinvalid.add("  ", " ");

            for (int i = 0; i < 99; i++)
            {
                //处理次数
                int j = 0;
                //处理开头[ and]
                if (strwhere.length >= 3)
                {
                    if (strwhere.toupper().substring(0, 3) == "and")
                    {
                        strwhere = strwhere.substring(3, strwhere.length - 3).trim();
                        j++;
                    }
                }

                //处理开头是[ or]
                if (strwhere.length >= 2)
                {
                    if (strwhere.toupper().substring(0, 2) == "or")
                    {
                        strwhere = strwhere.substring(2, strwhere.length - 2).trim();
                        j++;
                    }
                }
                //处理字典无效关键字
                foreach (keyvaluepair<string, string> dict in dictinvalid)
                {
                    if (strwhere.contains(dict.key))
                    {
                        strwhere = strwhere.replace(dict.key, dict.value).trim();
                        j++;
                    }
                }
                //处理末尾[ and]
                if (strwhere.length >= 3)
                {
                    if (strwhere.length - 3 == strwhere.toupper().lastindexof("and"))
                    {
                        strwhere = strwhere.substring(0, strwhere.length - 3).trim();
                        j++;
                    }
                }

                //处理末尾是[ or]
                if (strwhere.length >= 2)
                {
                    if (strwhere.length - 2 == strwhere.toupper().lastindexof("or"))
                    {
                        strwhere = strwhere.substring(0, strwhere.length - 2).trim();
                        j++;
                    }
                }
                //无处理次数时退出
                if (j == 0)
                {
                    break;
                }
            }

            //返加值
            if (lstparams.count > 0)
            {
                parameters = lstparams.toarray();
            }

            return strwhere.trim();
        }
        #endregion
    }

    6、新建一个winform窗体,命名为:generalquery。加入3个panel,分别命名为:toppanel、middlepanel、bottompanel。toppanel拖入上面新建的conditioncontrol,

middlepanel拖入一个datagridview,bottompanel拖入一个自定义分页控件(详情请看:datagridview使用自定义控件实现简单分页功能)。

C#通用查询器

    7、generalquery的代码实现:

        //委托及事件
        public delegate void returnresult(dictionary<string, object> dicts);
        public event returnresult returnresultevent;

        //属性
        public string[] fieldnames { get; set; }            //字段名
        public string[] fieldtypes { get; set; }            //字段数据类型
        public string[] fieldtexts { get; set; }            //字段文本
        public string[] fieldresults { get; set; }          //要返回的字段结果
        public stringbuilder totalcountsql { get; set; }    //总记录数sql
        public stringbuilder pagesql { get; set; }          //分页sql(需包含@pagesize、@pageindex,条件需包含@where。)
        public int pagesize { get; set; } = 12;             //每页显示记录数


        public generalquery()
        {
            initializecomponent();
        }

        private void generalquery_load(object sender, eventargs e)
        {
            try
            {
                //条件控件赋初始值
                if (fieldnames != null)
                    array.copy(fieldnames, conditioncontrol1.fieldnames, fieldnames.length);
                if (fieldtypes != null)
                    array.copy(fieldtypes, conditioncontrol1.fieldtypes, fieldtypes.length);
                if (fieldtexts != null)
                    array.copy(fieldtexts, conditioncontrol1.fieldtexts, fieldtexts.length);
                conditioncontrol1.targetcontrol = toppanel;
                conditioncontrol1.initialize();

                //datagridview1初始化
                if (conditioncontrol1.verifyfieldmatch())
                {
                    for (int i = 0; i < fieldnames.length; i++)
                    {
                        datagridviewtextboxcolumn textboxcolumn = new datagridviewtextboxcolumn
                        {
                            name = fieldnames[i].tostring(),
                            datapropertyname = fieldnames[i].tostring(),
                            headertext = fieldtexts[i].tostring()
                        };
                        datagridview1.columns.add(textboxcolumn);
                    }
                }

                //分页控件赋初始值
                pagecontrol1.pagesize = pagesize;
                pagecontrol1.pageindex = 0;
                pagecontrol1.bindpageevent += bindpage;
            }
            catch(exception ex)
            {
                messagebox.show(ex.message, "提示", messageboxbuttons.ok, messageboxicon.information);
            }
        }

        /// <summary>
        /// 绑定页
        /// </summary>
        /// <param name="pagesize">每页显示记录数</param>
        /// <param name="pageindex">页序号</param>
        /// <param name="totalcount">总记录数</param>
        private void bindpage(int pagesize, int pageindex, out int totalcount)
        {
            totalcount = 0;
            try
            {
                if (conditioncontrol1.verifyfieldmatch())
                {
                    string totalcountsql = totalcountsql.tostring();
                    string pagesql = pagesql.tostring();
                    pagesql = pagesql.replace("@pagesize", pagesize.tostring()).replace("@pageindex", pageindex.tostring()).tostring();
                    string strwhere = conditioncontrol1.getwherecondition(out sqlparameter[] parameters);
                    if (strwhere != string.empty)
                    {
                        strwhere = "(" + strwhere + ")";
                        totalcountsql = totalcountsql.replace("@where", strwhere);
                        pagesql = pagesql.replace("@where", strwhere);
                    }
                    else
                    {
                        totalcountsql = totalcountsql.replace("@where", "1=2");
                        pagesql = pagesql.replace("@where", "1=2");
                    }
                    totalcount = (int)dbhelper.getscalar(totalcountsql, parameters);
                    datatable dt = dbhelper.gettable(pagesql, parameters);
                    datagridview1.datasource = dt;
                }
            }
            catch (exception ex)
            {
                messagebox.show(ex.message, "提示", messageboxbuttons.ok, messageboxicon.information);
            }
        }

        /// <summary>
        /// 自动编号
        /// </summary>
        /// <param name="sender"></param>
        /// <param name="e"></param>
        private void datagridview1_rowpostpaint(object sender, datagridviewrowpostpainteventargs e)
        {
            rectangle rectangle = new rectangle
                (
                    e.rowbounds.location.x,
                    e.rowbounds.location.y,
                    datagridview1.rowheaderswidth - 4,
                    e.rowbounds.height
                );
            textrenderer.drawtext
                (
                    e.graphics,
                    (e.rowindex + 1).tostring(),
                    datagridview1.rowheadersdefaultcellstyle.font,
                    rectangle,
                    datagridview1.rowheadersdefaultcellstyle.forecolor,
                    textformatflags.verticalcenter | textformatflags.right
                );
        }

        /// <summary>
        /// 查询
        /// </summary>
        /// <param name="sender"></param>
        /// <param name="e"></param>
        private void btnsearch_click(object sender, eventargs e)
        {
            try
            {
                pagecontrol1.pageindex = 0;
                pagecontrol1.setpage();
            }
            catch (exception ex)
            {
                messagebox.show(ex.message, "提示", messageboxbuttons.ok, messageboxicon.information);
            }
        }

        /// <summary>
        /// 查看条件
        /// </summary>
        /// <param name="sender"></param>
        /// <param name="e"></param>
        private void btncondition_click(object sender, eventargs e)
        {
            string strwhere = conditioncontrol1.getwherecondition(out sqlparameter[] parameters);
            if (parameters != null)
            {
                foreach (sqlparameter param in parameters)
                {
                    strwhere += "," + param.parametername + "=" + param.sqlvalue;
                }
            }
            messagebox.show(strwhere, "提示", messageboxbuttons.ok, messageboxicon.information);
        }

        /// <summary>
        /// 关闭
        /// </summary>
        /// <param name="sender"></param>
        /// <param name="e"></param>
        private void btnclose_click(object sender, eventargs e)
        {
            close();
        }

        /// <summary>
        /// 双击返回字典
        /// </summary>
        /// <param name="sender"></param>
        /// <param name="e"></param>
        private void datagridview1_celldoubleclick(object sender, datagridviewcelleventargs e)
        {
            try
            {
                if (fieldresults != null)
                {
                    dictionary<string, object> dictresult = new dictionary<string, object>();
                    for (int i = 0; i < fieldresults.length; i++)
                    {
                        if (datagridview1.columns.contains(fieldresults[i]))
                        {
                            dictresult.add(fieldresults[i], datagridview1.rows[e.rowindex].cells[fieldresults[i]].value);
                        }
                    }
                    if (dictresult.count > 0)
                    {
                        returnresultevent(dictresult);
                    }
                    else
                    {
                        returnresultevent(null);
                    }
                    close();
                }
            }
            catch(exception ex)
            {
                messagebox.show(ex.message, "提示", messageboxbuttons.ok, messageboxicon.information);
            }
        }

    8、以上,通用查询器的功能就全部实现了,下面来调用一下: 新建一个winform窗体,命名为:main。

C#通用查询器

     9、main的代码实现:

        /// <summary>
        /// 调用通用查询器
        /// </summary>
        /// <param name="sender"></param>
        /// <param name="e"></param>
        private void button1_click(object sender, eventargs e)
        {
            generalquery query = new generalquery
            {
                fieldnames = new string[] { "mo_no", "mo_dd", "mrp_no", "qty", "bil_no" },
                fieldtypes = new string[] { "varchar", "datetime", "varchar", "decimal", "varchar" },
                fieldtexts = new string[] { "制令单号", "制令单日期", "成品编号", "生产数量", "来源单号" },
                fieldresults = new string[] { "mo_no" },
                totalcountsql = new stringbuilder()
            };
            query.totalcountsql.append("select count(1) from mf_mo where @where");
            query.pagesql = new stringbuilder();
            query.pagesql.append
                (
                    "select top (@pagesize) mo_no,mo_dd,mrp_no,qty,bil_no " +
                    "from mf_mo a " +
                    "where @where and not exists (select 1 from (select top ((@pageindex - 1) * @pagesize) mo_no from mf_mo where @where order by mo_no) b where a.mo_no=b.mo_no) " +
                    "order by mo_no"
                );
            query.returnresultevent += query_returnresultevent;
            query.showdialog();
        }

        /// <summary>
        /// 委托函数
        /// </summary>
        /// <param name="dicts"></param>
        private void query_returnresultevent(dictionary<string, object> dicts)
        {
            if(dicts!=null)
            {
                foreach(keyvaluepair<string,object> dict in dicts)
                {
                    if(dict.key=="mo_no")
                    {
                        messagebox.show(string.format("mo_no传回的值是:{0}", dict.value.tostring()), "提示", messageboxbuttons.ok, messageboxicon.information);
                    }
                }
            }
        }

    10、效果:

C#通用查询器

 C#通用查询器

     好了,分享就到此结束了,希望对有此需要的人有一些帮助。