Warning: file_get_contents(/data/phpspider/zhask/data//catemap/2/csharp/283.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

Warning: file_get_contents(/data/phpspider/zhask/data//catemap/6/ant/2.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# 最好将打开的SqlConnection作为参数传递,还是在每个方法中调用一个新的连接?_C#_Sqlconnection - Fatal编程技术网

C# 最好将打开的SqlConnection作为参数传递,还是在每个方法中调用一个新的连接?

C# 最好将打开的SqlConnection作为参数传递,还是在每个方法中调用一个新的连接?,c#,sqlconnection,C#,Sqlconnection,如果我要调用的方法/函数需要一个开放的SqlConnection,我将在调用该函数的方法中打开它。例如: protected static void btnSubmit(){ conn.Open(); myMethod(someParam, conn); conn.Close(); } protected static void myMethod(object someParam, SqlConnection conn){ //Some SQL commands etc

如果我要调用的方法/函数需要一个开放的SqlConnection,我将在调用该函数的方法中打开它。例如:

protected static void btnSubmit(){
   conn.Open();
   myMethod(someParam, conn);
   conn.Close();
}

protected static void myMethod(object someParam, SqlConnection conn){
   //Some SQL commands etc here..
}
我这样做是为了:

  • 每个进程仅打开和关闭1个SqlConnection
但是,这样构造我的代码是否更好:

protected static void btnSubmit(){
   myMethod(someParam);
}

protected static void myMethod(object someParam){
   SqlConnection conn = New SqlConnection(".....");
   conn.Open();
   //Some SQL commands etc here..
   conn.Close();
}
我认为这种结构的优点是:

  • 我不必为每个方法传递额外的参数
  • 如果稍后该方法不再具有SQL命令,则每次都不会调用未使用的参数
我认为这样做的缺点是:

  • 如果
    myMethod
    是一个递归方法,那么当它调用自己时,它将打开另一个
    SqlConnection
    ,依此类推
  • 如果
    btnSubmit
    正在调用多个都需要SqlConnection的方法,则每个方法都将打开和关闭一个新连接

做这件事的最佳方法是什么,最常用的方法是什么?

ADO.NET使用连接池,因此它会自动重用现有打开的连接,即使您认为您正在打开一个新连接。记住这一点,实际上没有理由通过代码传递连接(作为参数)。这将使您的代码更加清晰,性能与您作为参数传递连接时相同

更多细节

另外(这非常重要),请使用“使用”关键字。这样,您就不必处理关闭连接和清理的问题,因为现在编写的代码不处理关闭连接的问题,因此在出现异常的情况下,您可能最终会达到服务器上的连接限制。这样做:

using(var connection = new SqlConnection(<connection_string>))
{
  connection.Open();
  using(var command = connection.CreateCommand())
  {

  }
}
使用(var connection=new SqlConnection())
{
connection.Open();
使用(var command=connection.CreateCommand())
{
}
}
如您所见,无需调用connection.Close()或处理异常并在
finally
块中关闭连接,因为这是“using”块的“作业”


另外,还有一个重要的注意事项……事务不是通过连接轮询传递的,因此,如果要在方法调用之间保持事务,则必须传递连接(这是我能想到为什么要这样做的唯一原因)。

最好使用的模式是+模式

因此,存储库被创建并传递包含连接的UnitOfWork。工作完成后,处理工作单元

// Pseudocode
using(UnitOfWork uow = new UnitOfWork())
{
   Repository.Init(uow);
   Repository.SaveInDb(stuff);
}
和工作单位:

// PseudoCode
class UnitOfWork : IDisposable
{
   public UnitOfWork()
   {
      conn = new SqlConnection();
      conn.Open();
   }

   public void Dispose()
   {
       conn.Close();
   }

 ....

}
这是我经常使用的


有些人更喜欢存储库拥有连接的简单方法。这更简单,但如果您需要跨多个存储库进行事务处理,它将不起作用。

因此,如果我为同一个数据库/登录打开100个不同的SqlConnection对象,这不会给处理带来任何额外的压力?为更多的细节干杯。因此,将我的
using
语句放在
myMethod
中(使用我的示例)是一种很好的做法吗?为了提高性能,我一直避免使用它,但如果它没有什么区别,那么它会变得更整洁!如果你不相信,做一个测试并尝试:)你会发现没有区别(至少不明显)。连接池中有一个属性说明最大池大小是多少(我认为100是默认值),请看这里:在“使用连接字符串关键字控制连接池”中Section I添加了一个关于事务的注释,因为在这里传递连接是有意义的。我想分享一下我最近的测试结果。。。在2560个并行线程上,10000个项目,每个项目需要10次对数据库的调用,每次调用2秒,打开了1556个并发连接,并且在不到10分钟内完成。+1甚至稍微暗示了更新数据库时应考虑事务边界这一事实。如果使用TransactionScope,它在多个存储库中工作得非常好,就像每个存储库都有自己的连接一样,连接将自动登记自己已生效的任何TransactionScope。有什么理由不这样做吗?