简体   繁体   English

C# sql 为每个查询创建一个连接并打开和关闭

[英]C# sql create one connection and open and close for each query

I recently inherited a C# Web app that creates a new connection for every query like so:我最近继承了一个 C# Web 应用程序,它为每个查询创建一个新连接,如下所示:

public class QueryForm
{
    public bool getStudents()
    {
        SqlConnection conn = new SqlConnection(ConfigurationManager.ConnectionStrings["conn"].ConnectionString);
        conn.Open();
        //commands
        conn.Close();
    }

    protected void getProfessors()
    {
        SqlConnection conn = new SqlConnection(ConfigurationManager.ConnectionStrings["conn"].ConnectionString);
        conn.Open();
        //Commands
        conn.Close();
    }


    protected void getProfessors()
    {
        SqlConnection conn = new SqlConnection(ConfigurationManager.ConnectionStrings["conn"].ConnectionString);
        conn.Open();
        //Commands
        conn.Close();
    }
}

I understand that this is typically the best way to do it, but is it acceptable or "best practice" to have the constructor create the connection object, and then have each method/Query open and then close that connection like so:我知道这通常是最好的方法,但是让构造函数创建连接对象,然后打开每个方法/查询,然后像这样关闭该连接是否可以接受或“最佳实践”:

public class QueryForm
{
    SqlConnection conn;

    public QueryForm()
    {
        conn = new SqlConnection(ConfigurationManager.ConnectionStrings["conn"].ConnectionString);
    }

    public bool getStudents()
    {
        conn.Open();
        //commands
        conn.Close();
    }

    protected void getProfessors()
    {
        conn.Open();
        //Commands
        conn.Close();
    }

    protected void getCourses()
    {
        conn.Open();
        //Commands
        conn.Close();
    }
}

I prefer the second way as it does not make multiple connection objects.我更喜欢第二种方式,因为它不会产生多个连接对象。 However, the first way would also be preferable if I were to make the methods and class static.但是,如果我要将方法和类设为静态,则第一种方法也更可取。

Either one of these are acceptable.其中任何一个都可以接受。 A SqlConnection uses a connection-pool so it shouldn't affect performance much. SqlConnection使用连接池,因此它不会对性能产生太大影响。 Having multiple SqlConnection objects isn't going to hurt anything.拥有多个SqlConnection对象不会有任何伤害。 This comes down to a preference.这归结为偏好。

I would suggest encapsulating the commands in a using statement if you keep the connections inside the methods, such as:如果您将连接保留在方法中,我建议将命令封装在using语句中,例如:

using (SqlConnection conn = new SqlConnection(...))
{
    conn.Open();
    //commands
    conn.Close();
}

This ensures proper disposal of the connection.这可确保正确处理连接。

It is important that you keep the connection open for the shortest possible time .尽可能短的时间内保持连接打开很重要。 SQL connection is using a connection pool so opening a connection actually reuses a connection behind the scenes. SQL 连接使用连接池,因此打开连接实际上是在幕后重用连接。 If you keep the connection open your at risk of running into error: 'Parallel transactions are not supported' if you use the method BeginTransaction .如果您保持连接打开,则您有遇到错误的风险:如果使用方法BeginTransaction ,则不支持“不支持并行事务”。

This being a web app with a potentially large number of connections, leaving the connection object open longer puts you in risk of exhausting the connection pool and getting: 'The timeout period elapsed prior to obtaining a connection from the pool' error.这是一个具有潜在大量连接的 Web 应用程序,让连接对象打开的时间更长会使您面临耗尽连接池并出现:“在从池中获取连接之前超时时间已过”错误的风险。

Additionally, you must make sure the connection is closed even if an exception is thrown.此外,即使抛出异常,您也必须确保连接已关闭。

This should be done with a using block like:这应该使用 using 块来完成,例如:

using (SqlConnection conn = new SqlConnection(...))
{
    conn.Open();
    //commands
}

since exiting a 'using' block calls .Dispose() on the used object.由于退出“使用”块对使用的对象调用 .Dispose() 。

or with a try / catch / finally block like:或使用 try / catch / finally 块,例如:

SqlConnection conn = null;

try
{
    conn = new SqlConnection(...);    
    conn.Open();
    //commands
}
catch(Exception ex)
{
    ...
}
finally
{
    if(conn != null)
        conn.Close();
}

声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM