C# 最好将打开的SqlConnection作为参数传递,还是在每个方法中调用一个新的连接?
如果我要调用的方法/函数需要一个开放的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
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
- 如果
正在调用多个都需要SqlConnection的方法,则每个方法都将打开和关闭一个新连接btnSubmit
做这件事的最佳方法是什么,最常用的方法是什么?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。有什么理由不这样做吗?