一旦查询执行显式调用Close方法或将连接放在Using语句中,是否有必要关闭连接?离开连接是否会导致连接重用并提高SQL性能以备将来查询?
Ami*_*shi 26
我假设您使用的是最新版本的Dapper.
使用Dapper,有两种方法可以管理连接:
全面管理自己: 在这里,您完全负责打开和关闭连接.这就像您在使用ADO.NET时处理连接一样.
允许Dapper管理它:
Dapper会自动打开连接(如果它没有打开)并为你关闭它(如果它是由Dapper打开的).这与DataAdapter.Fill()方法类似.我个人不推荐这种方式.这可能不适用于每次.以下是Marc Gravell在其中一条评论中所说的:https://stackoverflow.com/a/12629170/5779732
好吧,技术上的开/关与处理不同.如果您只打算在个别电话周围打开/关闭,那么您也可以让精打细算.如果您以更大的粒度打开/关闭(例如,根据请求),那么代码执行此操作并将打开的连接传递给dapper会更好.
以下是这里的引用:
如果需要打开它,Dapper将关闭连接.所以如果你只是做一个快速查询 - 让Dapper处理它.如果你做了很多,你应该打开(一次)并在结束时关闭,所有查询都在中间......只是从效率的角度来看.
当然,您可以在单个连接上调用多个查询.但是,应该关闭连接(通过调用Close(),Dispose()方法或将其封闭在using块中)以避免资源泄漏.关闭连接会将其返回到连接池.连接池的参与提高了新连接成本的性能.
除了处理连接之外,我建议你实现UnitOfWork来管理事务.在GitHub上参考这个优秀的样本.
以下源代码可以帮助您.请注意,这是根据我的需要编写的; 所以它可能不适合你.
public sealed class DalSession : IDisposable
{
public DalSession()
{
_connection = new OleDbConnection(DalCommon.ConnectionString);
_connection.Open();
_unitOfWork = new UnitOfWork(_connection);
}
IDbConnection _connection = null;
UnitOfWork _unitOfWork = null;
public UnitOfWork UnitOfWork
{
get { return _unitOfWork; }
}
public void Dispose()
{
_unitOfWork.Dispose();
_connection.Dispose();
}
}
public sealed class UnitOfWork : IUnitOfWork
{
internal UnitOfWork(IDbConnection connection)
{
_id = Guid.NewGuid();
_connection = connection;
}
IDbConnection _connection = null;
IDbTransaction _transaction = null;
Guid _id = Guid.Empty;
IDbConnection IUnitOfWork.Connection
{
get { return _connection; }
}
IDbTransaction IUnitOfWork.Transaction
{
get { return _transaction; }
}
Guid IUnitOfWork.Id
{
get { return _id; }
}
public void Begin()
{
_transaction = _connection.BeginTransaction();
}
public void Commit()
{
_transaction.Commit();
Dispose();
}
public void Rollback()
{
_transaction.Rollback();
Dispose();
}
public void Dispose()
{
if(_transaction != null)
_transaction.Dispose();
_transaction = null;
}
}
interface IUnitOfWork : IDisposable
{
Guid Id { get; }
IDbConnection Connection { get; }
IDbTransaction Transaction { get; }
void Begin();
void Commit();
void Rollback();
}
Run Code Online (Sandbox Code Playgroud)
现在,您的存储库应该以某种方式接受此UnitOfWork.我选择了使用Constructor的依赖注入.
public sealed class MyRepository
{
public MyRepository(IUnitOfWork unitOfWork)
{
this.unitOfWork = unitOfWork;
}
IUnitOfWork unitOfWork = null;
//You also need to handle other parameters like 'sql', 'param' ect. This is out of scope of this answer.
public MyPoco Get()
{
return unitOfWork.Connection.Query(sql, param, unitOfWork.Transaction, .......);
}
public void Insert(MyPoco poco)
{
return unitOfWork.Connection.Execute(sql, param, unitOfWork.Transaction, .........);
}
}
Run Code Online (Sandbox Code Playgroud)
然后你这样称呼它:
随着交易:
using(DalSession dalSession = new DalSession())
{
UnitOfWork unitOfWork = dalSession.UnitOfWork;
unitOfWork.Begin();
try
{
//Your database code here
MyRepository myRepository = new MyRepository(unitOfWork);
myRepository.Insert(myPoco);
//You may create other repositories in similar way in same scope of UoW.
unitOfWork.Commit();
}
catch
{
unitOfWork.Rollback();
throw;
}
}
Run Code Online (Sandbox Code Playgroud)
没有交易:
using(DalSession dalSession = new DalSession())
{
//Your database code here
MyRepository myRepository = new MyRepository(dalSession.UnitOfWork);//UoW have no effect here as Begin() is not called.
myRepository.Insert(myPoco);
}
Run Code Online (Sandbox Code Playgroud)
这样,您可以在一个位置控制它,而不是直接在您的调用代码中公开连接.
有关上述代码中存储库的更多详细信息,请参见此处.
请注意,UnitOfWork是更不仅仅是一个交易.此代码仅处理事务.您可以扩展此代码以涵盖其他角色.
| 归档时间: |
|
| 查看次数: |
14489 次 |
| 最近记录: |