首页 > 解决方案 > 在 C# 中处理数据库连接

问题描述

我正在使用 C# 和 SqlServer 创建 WinForm 应用程序。我必须在上面处理许多数据库 CRUD 查询。而且还有很多表格和很多控制器。

现在我想知道的是,如果我使用许多方法创建用于处理数据库连接的通用类,用于打开连接、关闭连接、执行 Sql 命令或进行任何其他数据检索。这种方法是好是坏?

或以下运行每个查询的方法是好是坏?

using (SqlConnection connection = new SqlConnection("Integrated Security=SSPI;Initial Catalog=MYDB"))  
{  
    connection.Open();        
    // Pool A is created.  
}  

哪种方法对性能和安全性更好?

标签: c#sqlconnection

解决方案


以下是使用连接时需要考虑的一些要点。

1) 使用 using 语句在不再需要连接对象时立即处理它:

using (var conn = new SqlConnection(connectionstring))  
{  
    // your sql magic goes here
} 

2) 如果您不立即处理对象,则可以使用 try-finally 语句确保连接已关闭:

var conn = new SqlConnection(connectionstring);
try
{
// do sql shizzle
}
finally
{
    conn.Close();
}           

3)为了防止SQL注入,使用参数化查询,从不连接字符串

using (var conn = new SqlConnection(connectionstring))  
{  
    conn.Open();
    using(var comm = new SqlCommand("select * from FooBar where foo = @foo", conn))
    {
        comm.Parameters.Add(new SqlParameter("@foo", "bar"));
        // also possible:
        // comm.Parameters.AddWithValue("@foo", "bar");
        using(var reader = comm.ExecuteReader())
        {
            // Do stuff with the reader;
        }
    }
} 

4) 如果您正在执行多个更新、插入或删除语句,并且它们都需要一次成功,请使用事务:

using (var conn = new SqlConnection(connectionstring))  
{  
    conn.Open();
    using(var trans = conn.BeginTransaction())
    {
        try 
        {
            using(var comm = new SqlCommand("delete from FooBar where fooId = @foo", conn, trans))
            {
                comm.Parameters.Add(new SqlParameter { ParameterName = "@foo", DbType = System.Data.DbType.Int32 });
                for(int i = 0; i < 10 ; i++)
                {
                    comm.Parameters["@foo"].Value = i;
                    comm.ExecuteNonQuery();
                }
            }
            trans.Commit();
        }
        catch (Exception exe)
        {
            trans.Rollback();
            // do some logging
        }
    }
} 

5)存储过程的使用类似:

using (var conn = new SqlConnection(connectionstring))
{
    conn.Open();
    using (var comm = new SqlCommand("FooBarProcedure", conn) { CommandType = CommandType.StoredProcedure }) 
    {
         comm.Parameters.Add(new SqlParameter("@FooBar", "shizzle"));
         comm.ExecuteNonQuery();
    }
}

(源存储过程:this Answer

多线程:使用多线程和 SQL 连接的最安全方法是始终关闭和处置您的连接对象。这是 SqlConnection 设计的行为。(来源:回答约翰斯基特


推荐阅读