用于搜索查询的try-catch语句和数据库连接

时间:2018-01-24 04:42:37

标签: c# try-catch database-connection

这些代码运行正常,但我仍然想知道是否需要对搜索查询使用 try-catch语句打开 - 关闭连接数据库。< / p>

您的建议将受到高度赞赏。

SqlConnection cn = new SqlConnection("Data Source = localhost; Integrated Security = True; Database = myDB;");
SqlDataAdapter adp = new SqlDataAdapter();

private void LoadSearch()
        {            
            switch (cmbCategory.Text)
            {
                case "All":                    
                    adp.SelectCommand = new SqlCommand("SELECT * FROM tblCommunication WHERE LetterType LIKE '" + txSearch.Text.Trim() + "' OR LetterNumber LIKE '" + txSearch.Text.Trim() + "' OR LetterAmount LIKE '" + txSearch.Text.Trim() + "' OR LetterFrom LIKE '" + txSearch.Text.Trim() + "' OR LetterTo LIKE '" + txSearch.Text.Trim() + "' OR ReceivedBy LIKE '" + txSearch.Text.Trim() + "' OR Requisition LIKE '" + txSearch.Text.Trim() + "' OR LetterSubject LIKE '" + txSearch.Text.Trim() + "' OR LetterContent LIKE '" + txSearch.Text.Trim() + "' OR LetterRemarks LIKE '" + txSearch.Text.Trim() + "'", cn);
                    DataTable dtAll = new DataTable();
                    //cn.Open();
                    adp.Fill(dtAll);
                    dgCommunications.DataSource = dtAll;
                    //cn.Close();                    
                    break;

                case "Incoming Communications":
                    adp.SelectCommand = new SqlCommand("SELECT CommType = '" + cmbCategory.Text + "', LetterDate, LetterReceived, LetterType, LetterNumber, LetterAmount, LetterFrom, LetterTo, ReceivedBy, Requisition, LetterSubject, LetterContent, LetterRemarks FROM tblCommunication WHERE LetterType LIKE '" + txSearch.Text.Trim() + "' OR LetterNumber LIKE '" + txSearch.Text.Trim() + "' OR LetterAmount LIKE '" + txSearch.Text.Trim() + "' OR LetterFrom LIKE '" + txSearch.Text.Trim() + "' OR LetterTo LIKE '" + txSearch.Text.Trim() + "' OR ReceivedBy LIKE '" + txSearch.Text.Trim() + "' OR Requisition LIKE '" + txSearch.Text.Trim() + "' OR LetterSubject LIKE '" + txSearch.Text.Trim() + "' OR LetterContent LIKE '" + txSearch.Text.Trim() + "' OR LetterRemarks LIKE '" + txSearch.Text.Trim() + "'", cn);
                    DataTable dtInc = new DataTable();
                   // cn.Open();
                    adp.Fill(dtInc);
                    dgCommunications.DataSource = dtInc;
                    //cn.Close();
                    break;

                case "Inside Communications":
                    adp.SelectCommand = new SqlCommand("SELECT CommType = '" + cmbCategory.Text + "', LetterDate, LetterReceived, LetterType, LetterNumber, LetterAmount, LetterFrom, LetterTo, ReceivedBy, Requisition, LetterSubject, LetterContent, LetterRemarks FROM tblCommunication WHERE LetterType LIKE '" + txSearch.Text.Trim() + "' OR LetterNumber LIKE '" + txSearch.Text.Trim() + "' OR LetterAmount LIKE '" + txSearch.Text.Trim() + "' OR LetterFrom LIKE '" + txSearch.Text.Trim() + "' OR LetterTo LIKE '" + txSearch.Text.Trim() + "' OR ReceivedBy LIKE '" + txSearch.Text.Trim() + "' OR Requisition LIKE '" + txSearch.Text.Trim() + "' OR LetterSubject LIKE '" + txSearch.Text.Trim() + "' OR LetterContent LIKE '" + txSearch.Text.Trim() + "' OR LetterRemarks LIKE '" + txSearch.Text.Trim() + "'", cn); ;
                    DataTable dtIns = new DataTable();
                    //cn.Open();
                    adp.Fill(dtIns);
                    dgCommunications.DataSource = dtIns;
                    //cn.Close();
                    break;

                case "Outgoing Communications":
                    adp.SelectCommand = new SqlCommand("SELECT CommType = '" + cmbCategory.Text + "', LetterDate, LetterReceived, LetterType, LetterNumber, LetterAmount, LetterFrom, LetterTo, ReceivedBy, Requisition, LetterSubject, LetterContent, LetterRemarks FROM tblCommunication WHERE LetterType LIKE '" + txSearch.Text.Trim() + "' OR LetterNumber LIKE '" + txSearch.Text.Trim() + "' OR LetterAmount LIKE '" + txSearch.Text.Trim() + "' OR LetterFrom LIKE '" + txSearch.Text.Trim() + "' OR LetterTo LIKE '" + txSearch.Text.Trim() + "' OR ReceivedBy LIKE '" + txSearch.Text.Trim() + "' OR Requisition LIKE '" + txSearch.Text.Trim() + "' OR LetterSubject LIKE '" + txSearch.Text.Trim() + "' OR LetterContent LIKE '" + txSearch.Text.Trim() + "' OR LetterRemarks LIKE '" + txSearch.Text.Trim() + "'", cn); ;
                    DataTable dtOut = new DataTable();
                    //cn.Open();
                    adp.Fill(dtOut);
                    dgCommunications.DataSource = dtOut;
                   // cn.Close();
                    break;                
            }            
        }

2 个答案:

答案 0 :(得分:0)

最好的方法之一是使用声明

using (SqlConnection connection = new SqlConnection(conString))
{
    try
    {
        //your switch case statement
    }
    catch (InvalidOperationException)
    {

    }
    catch (SqlException)
    {

    }
}

单向,您可以为所有情况编写一个comman方法,如下所示,并在所有情况下调用此方法

public void Command(string query,string conString)
{
    SqlDataAdapter adp = new SqlDataAdapter();
    using (SqlConnection connection = new SqlConnection(conString))
    {

        try
        {
            adp.SelectCommand = new SqlCommand(query,connection);
            DataTable dtOut = new DataTable();
            adp.Fill(dtOut);
            dgCommunications.DataSource = dtOut;
        }
        catch (InvalidOperationException)
        {

        }
        catch (SqlException)
        {

        }
    }
}

或者可以像这样使用

SqlDataAdapter adp = new SqlDataAdapter();
using (SqlConnection connection = new SqlConnection(conString))
{

    try
    {
        switch (cmbCategory.Text)
        {
            case "All":                    
                break;

        }
    }
    catch (InvalidOperationException)
    {

    }
    catch (SqlException)
    {

    }
}

答案 1 :(得分:0)

问题中提供的代码是如何不编写代码的主要示例。

  1. 使用字符串连接来创建SQL语句是一种安全风险 - 因为它是SQL注入攻击的一扇门。 始终在将用户输入传递到数据库时使用参数。

  2. 大多数代码都在重复。事实上,在switch分支中唯一不同的是SQL语句。

  3. 在处理实现using接口的类的实例时,始终使用IDisposable语句 - 并且所有ADO.Net类都是IDisposable。这将确保您的实例被处置。

  4. 使用&#34;魔术字符串&#34;在你的案例陈述中。更好的解决方案是使用带常量的指定类,而不是在整个代码中使用魔术字符串。

  5. 您的代码涉及UI元素和数据库访问 - 这里没有关注点。

  6. 那你应该怎么写呢?

    那么,你应该使用某种n层架构设计模式 - MVC,MVP和MVVM是n层的一些常见实现。

    这太宽泛了,无法在SO帖子中完全解释,但基本上它意味着你的代码应该被分成(至少)3个不同的部分:数据访问层,业务逻辑层和UI (用户界面)图层。

    最简单的3层形式是拥有一个数据访问类,每个表单/窗口的UI一个类,以及每个表单/窗口的业务逻辑一个类。

    因此,对于数据访问,请设置一个用于与数据库通信的类 这个类应该对UI一无所知,也不了解业务逻辑。它只需要有CRUD方法 - 创建,读取,更新和删除数据。

    根据您的上述代码,您可以使用以下内容:

    class DAL
    {
        private readonly string _connectionString;
        public DAL(string connectionString)
        {
            _connectionString = connectionString;
        }
    
        public DataTable SearchAll(string searchText)
        {
            var sql = "SELECT * FROM tblCommunication "+
                      "WHERE LetterType = @searchText "+
                      "OR LetterNumber = @searchText  "+
                      "OR LetterAmount = @searchText  "+
                      "OR LetterFrom  = @searchText  "+
                      "OR LetterTo  = @searchText  "+
                      "OR ReceivedBy  = @searchText  "+
                      "OR Requisition  = @searchText  "+
                      "OR LetterSubject  = @searchText  "+
                      "OR LetterContent  = @searchText  "+
                      "OR LetterRemarks  = @searchText";
    
            var parameter = new SqlParameter("@searchText", SqlDbType.VarChar);
            parameter.Value = searchText;
            return GetDataTable(sql, CommandType.Text, parameter);
        }
    
        public DataTable SearchIncomingCommunications(string caterogy, string searchText) 
        { 
            // implementation same as the example above
            throw new NotImplementedException();
        }
    
        public DataTable SearchInsideCommunications(string caterogy, string searchText)
        {
            // implementation same as the example above
            throw new NotImplementedException();
        }
    
        // add other methods as well
    
     private DataTable GetDataTable(string sql, CommandType commandType, params SqlParameter[] parameters)
        {
            var dt = new DataTable();
            using (var con = new SqlConnection(_connectionString))
            {
                using (var cmd = new SqlCommand(sql, con))
                {
                    cmd.CommandType = commandType;
                    foreach (var parameter in parameters)
                    {
                        cmd.Parameters.Add(parameter);
                    }
                    using (var da = new SqlDataAdapter(cmd))
                    {
                        da.Fill(dt);
                    }
                }
            }
            return dt;
        }
    }
    

    然后,在业务逻辑类中,根据您从UI获得的输入,将switch语句确定为要返回的数据表。 最后,在用户界面中,您将DataTabledgCommunications数据源相关联。

    关于错误处理 - 嗯,这不属于数据访问层。它属于业务逻辑层 - 因为在数据访问层中,您几乎无能为力。有关详细信息,请阅读softwareengineering.stackexchange.com上的this question

    我会进一步解释,但我怀疑我已经超出了单个Stack Overflow答案的范围。其余的如果留给你研究。一个好的起点是This SO question及其答案。