Warning: file_get_contents(/data/phpspider/zhask/data//catemap/2/csharp/276.json): failed to open stream: No such file or directory in /data/phpspider/zhask/libs/function.php on line 167

Warning: Invalid argument supplied for foreach() in /data/phpspider/zhask/libs/tag.function.php on line 1116

Notice: Undefined index: in /data/phpspider/zhask/libs/function.php on line 180

Warning: array_chunk() expects parameter 1 to be array, null given in /data/phpspider/zhask/libs/function.php on line 181
C# 管理SQL Server连接_C#_.net_Sql Server_Connection Pooling_Sqlconnection - Fatal编程技术网

C# 管理SQL Server连接

C# 管理SQL Server连接,c#,.net,sql-server,connection-pooling,sqlconnection,C#,.net,Sql Server,Connection Pooling,Sqlconnection,SQL连接的最佳实践是什么 目前我正在使用以下工具: using (SqlConnection sqlConn = new SqlConnection(CONNECTIONSTRING)) { sqlConn.Open(); // DB CODE GOES HERE } 我已经读到,这是一种非常有效的SQL连接方式。默认情况下,SQL池是活动的,因此我的理解是,当using代码结束时,SqlConnection对象被关闭并释放,但到DB的实际连接被放在SQL连接池中。我错了吗?

SQL连接的最佳实践是什么

目前我正在使用以下工具:

using (SqlConnection sqlConn = new SqlConnection(CONNECTIONSTRING))
{
    sqlConn.Open();
    // DB CODE GOES HERE
}

我已经读到,这是一种非常有效的SQL连接方式。默认情况下,SQL池是活动的,因此我的理解是,当
using
代码结束时,
SqlConnection
对象被关闭并释放,但到DB的实际连接被放在SQL连接池中。我错了吗?

您对使用的理解是正确的,推荐使用这种方法。您还可以在代码中调用close。

这就是它的大部分内容。需要考虑的其他几点:

  • 您从哪里获得连接字符串?你不希望到处都是硬编码,你可能需要保护它
  • 在真正使用连接之前,通常还需要创建其他对象(
    SqlCommand
    SqlParameter
    DataSet
    SqlDataAdapter
    ),并且您希望尽可能长时间地等待以打开连接。整个模式需要考虑到这一点
  • 您希望确保数据库访问被强制进入它自己的数据层类或程序集。因此,一个常见的做法是将其表示为私有函数调用:

然后像这样写下你的样本:

using (SqlConnection sqlConn = getConnection())
{
    // create command and add parameters

    // open the connection
    sqlConn.Open();

   // run the command
}
public IEnumerable<IDataRecord> GetSomeData(string filter)
{
    string sql = "SELECT * FROM [SomeTable] WHERE [SomeColumn] LIKE @Filter + '%'";

    using (SqlConnection cn = getConnection())
    using (SqlCommand cmd = new SqlCommand(sql, cn))
    {
        cmd.Parameters.Add("@Filter", SqlDbType.NVarChar, 255).Value = filter;
        cn.Open();

        using (IDataReader rdr = cmd.ExecuteReader())
        {
            while (rdr.Read())
            {
                yield return (IDataRecord)rdr;
            }
        }
    }
}
该示例只能存在于数据访问类中。另一种方法是将其标记为
internal
,并将数据层分布在整个程序集上。最重要的是,严格执行数据库代码的干净分离

真正的实现可能如下所示:

using (SqlConnection sqlConn = getConnection())
{
    // create command and add parameters

    // open the connection
    sqlConn.Open();

   // run the command
}
public IEnumerable<IDataRecord> GetSomeData(string filter)
{
    string sql = "SELECT * FROM [SomeTable] WHERE [SomeColumn] LIKE @Filter + '%'";

    using (SqlConnection cn = getConnection())
    using (SqlCommand cmd = new SqlCommand(sql, cn))
    {
        cmd.Parameters.Add("@Filter", SqlDbType.NVarChar, 255).Value = filter;
        cn.Open();

        using (IDataReader rdr = cmd.ExecuteReader())
        {
            while (rdr.Read())
            {
                yield return (IDataRecord)rdr;
            }
        }
    }
}
public IEnumerable GetSomeData(字符串过滤器)
{
string sql=“从[SomeTable]中选择*,其中[SomeColumn]类似于@Filter+'%'”;
使用(SqlConnection cn=getConnection())
使用(SqlCommand cmd=newsqlcommand(sql,cn))
{
cmd.Parameters.Add(“@Filter”,SqlDbType.NVarChar,255)。Value=Filter;
cn.Open();
使用(IDataReader rdr=cmd.ExecuteReader())
{
while(rdr.Read())
{
收益率回报率(IDataRecord)rdr;
}
}
}
}
注意,我还能够“堆叠”创建
cn
cmd
对象,从而减少嵌套,只创建一个范围块


最后,在此特定示例中使用
yield return
代码时要注意一点。如果调用该方法,但没有立即完成
数据绑定
或其他使用,则可能会使连接长时间保持打开状态。例如,使用它在ASP.NET页面的
Load
事件中设置数据源。由于实际的数据绑定事件直到稍后才会发生,因此您可以将连接保持在打开状态的时间比需要的时间长得多。

Microsoft的库是处理数据库连接的极好方法。这些库封装了打开连接所涉及的大多数机制,从而使您的生活更加轻松

另外:晚开早关


在调用数据库之前,在没有更多步骤之前不要打开连接。完成后立即关闭连接。

谢谢。我的理解是,当“使用”完成时,调用SqlConnection.Dispose();最后一个命令是调用SqlConnection.Close()@Neale-Yea,如果需要,SqlConnection.Dispose()将调用Close。如果连接已经关闭,它只需将句柄释放回ado.net提供程序,然后ado.net提供程序就可以将其放在池中或实际关闭它。第1点:我将连接字符串存储在app/web.config部分第2点:这是我应该担心的问题吗。我通常做SqlConnection,然后打开它,然后创建sqlCommand,然后从那里获取if。第3点:我们从一个类库进行所有的数据库访问。我不喜欢从核心应用程序访问数据库。创建getConnection方法值得吗?因为所有db访问都使用一个类库,所以将连接字符串作为类库的.config文件的一部分,而不是整个应用程序的全局.config文件,这很简单。这应该足以强制执行干净的数据层分离,但同时也没有理由公开该方法。这应该解决第1点和第3点。对于第二点来说,打开一两行可能不会有任何伤害,但也没有任何帮助。我在编辑的另一个原因是,您可能希望这样做。您的
收益率回报率
示例有点误导。在
IEnumerator
上第一次调用
MoveNext()
之前,围绕
yield return构建的函数不会开始执行。因此,即使您调用该函数,在您开始迭代结果之前,连接也不会打开。@ScottChamberlain这是一个功能,而不是一个bug(请参见第二个要点)。很抱歉,我不清楚,我的意思是说您的
收益返回
示例的描述有点误导。它谈到在调用该方法后保持连接打开,但实际上并没有。我同意一旦枚举开始,它会保持连接打开,您应该尝试尽快完成绑定以关闭它。我认为“如果你调用该方法…”这句话让我停下来写下了评论,我只是不知道该用什么来代替它更具描述性。