gpt4 book ai didi

c# - 试图避免嵌套的 SqlConnection

转载 作者:行者123 更新时间:2023-11-30 16:59:57 28 4
gpt4 key购买 nike

我不确定嵌套的 SqlConnections 是否可行,但我真的很想远离它。我现在在我的代码中遇到了一个范围问题,我正试图弄清楚如何解决它。

所以直到最近我还有一个全局 SqlConnection,它在应用程序启动时打开,在应用程序完成时关闭。我现在发现了 .NET 连接池的概念,所以我更改了我的代码,使每个 SqlCommand(或它们的组)都使用自己的新创建和打开的 SqlConnection,信任 .NET 来管理池和伴随的开销。

我现在遇到的问题是我有几个代码块看起来像这样:

using (SqlConnection sqlConnection = new SqlConnection(ClassGlobal.ConnectionString))
{
sqlConnection.Open();
using (SqlCommand sqlCommand1 = new SqlCommand("SQL code here", sqlConnection))
{
sqlCommand1.ExecuteNonQuery();
}
using (SqlCommand sqlCommand2 = new SqlCommand("SQL code here", sqlConnection))
{
sqlCommand2.ExecuteNonQuery();
}
.
.
.
ClassGlobal.WriteAction(action);
}

虽然 ClassGlobal.WriteAction() 函数看起来像这样:

public static void WriteAction(MyActionClass action)
{
using (SqlConnection sqlConnection = new SqlConnection(ClassGlobal.ConnectionString))
{
sqlConnection.Open();
using (SqlCommand sqlCommand = new SqlCommand("Write the action to the DB", sqlConnection))
{
sqlCommand.ExecuteNonQuery();
}
}
}

如您所见,在 WriteAction() 中创建了一个新的 SqlConnection,它是从第一个 SqlConnection 的范围内调用的。不好!我正在努力避免这种情况。

在过去,这不会是一个问题,因为没有这些 using (SqlConnection) block 并且所有 SqlCommands 都指向相同的(全局) SQLConnection。显然,我可以简单地将对 WriteAction() 的调用移动到 using (SqlCommand) 的右大括号下方,但是:

  1. 我传递给它的 action 实例通常在 SqlConnection 的范围内被实例化和填充,所以我必须做更多的改变(很多) 将它们移出 SqlConnection 范围。它们有很多,而且会很毛茸茸。
  2. 实际上,如果 WriteAction() 调用可以在 SqlConnection 范围内,如上例所示,我实际上更愿意,这样我就可以将其全部包装在一个 TransactionScope,这是迄今为止不可能实现的,但看起来确实是个好主意。

这就是我打算做的事情,但我想听听你们是否认为这不是一个好的做法,或者你们是否可以提出更好的方法。 (我最近发现我的全局 SqlConnection 不是一个好的做法,导致我花了很多时间来修复它。我希望以后避免这样的发现)。

如何向 WriteAction() 函数添加一个参数,使其如下所示:

public static void WriteAction(MyActionClass action, SqlConnection sqlConnection)
{
using (SqlCommand sqlCommand = new SqlCommand("Write the action to the DB", sqlConnection))
{
sqlCommand.ExecuteNonQuery();
}
}

这意味着,与其将对 WriteAction() 的调用移动到 SqlConnection 范围之外,我还可以简单地将 SqlConnection 添加为函数的一个参数,以便函数内的 SQLCommand 使用相同的连接,即使该连接已登记到 TransactionScope

对于我从任何 SqlConnection 范围之外调用 WriteAction() 的少数情况,我可以编写一个如下所示的重载函数:

public static void WriteAction(MyActionClass action)
{
using (TransactionScope transactionScope = new TransactionScope())
{
using (SqlConnection sqlConnection = new SqlConnection(ClassGlobal.ConnectionString))
{
sqlConnection.Open();
WriteAction(action, sqlConnection);
}
transactionScope.Complete();
}
}

这看起来是个好主意还是我会在再过两年后悔这个决定?

最佳答案

SqlConnection 实例传递给方法绝对没问题。但是,我不确定您是否采用了最后一种方法,没有 SqlConnection 的重载方法是个好主意。它隐藏了一个事实,即您应该更好地使用另一个新的重载。它使代码可以编译,从而阻止您修复现在应该修复的代码。

请注意,using block 不是问题,而是打开的连接。只要不打开连接,连接池就不需要打开物理连接。

因此,在调用 WriteAction 之前关闭连接也是一个可行的选择:

using (SqlConnection sqlConnection = new SqlConnection(ClassGlobal.ConnectionString))
{
sqlConnection.Open();
using (SqlCommand sqlCommand1 = new SqlCommand("SQL code here", sqlConnection))
{
sqlCommand1.ExecuteNonQuery();
}
using (SqlCommand sqlCommand2 = new SqlCommand("SQL code here", sqlConnection))
{
sqlCommand2.ExecuteNonQuery();
}
// ...
sqlConnection.Close();

ClassGlobal.WriteAction(action);

// ... perhaps open it again here
}

来自 MSDN :

Whenever a user calls Open on a connection, the pooler looks for an available connection in the pool. If a pooled connection is available, it returns it to the caller instead of opening a new connection. When the application calls Close on the connection, the pooler returns it to the pooled set of active connections instead of closing it. Once the connection is returned to the pool, it is ready to be reused on the next Open call.

所以你可以看到在WriteAction中嵌套的using是没有问题的,只要你不保持外部连接打开。不要将连接实例与物理连接混淆。

关于c# - 试图避免嵌套的 SqlConnection,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/22955341/

28 4 0
Copyright 2021 - 2024 cfsdn All Rights Reserved 蜀ICP备2022000587号
广告合作:1813099741@qq.com 6ren.com