这是处理 SQLConnection 的正确方法吗
我想知道我的下面的实现是否是在这种情况下处理 SQLconnection 的最有效方法。
我知道通常如果我直接使用 SqlConnection,我可以将连接包装在 using 块中以自动将其释放,但在这种情况下,我想保持连接打开并可用于 SQLRespository 类中的所有方法。
public class SqlRepository : IRepository
{
private readonly string connectionString;
private SqlConnection connection;
public SqlRepository(string connectionString)
{
this.connectionString = connectionString;
connection = new SqlConnection(connectionString);
connection.Open();
}
public void Method_A()
{
// uses the SqlConnection to fetch data
}
public void Method_B()
{
// uses the SqlConnection to fetch data
}
public void Dispose()
{
connection.Dispose();
}
}
用法:
using (IRepository repository = new SqlRepository(connectionString))
{
var item = repository.items;
}
更新 IRepository 确实实现了 IDisposable
I was wondering if my below implementation is the most efficient way to dispose the SQLconnection in this case.
I know normally if i'm using the SqlConnection directly I can just wrap the connection inside a using block to dispose it off automatically, but in this case i wanted to keep the connection open and available to All methods in the SQLRespository class.
public class SqlRepository : IRepository
{
private readonly string connectionString;
private SqlConnection connection;
public SqlRepository(string connectionString)
{
this.connectionString = connectionString;
connection = new SqlConnection(connectionString);
connection.Open();
}
public void Method_A()
{
// uses the SqlConnection to fetch data
}
public void Method_B()
{
// uses the SqlConnection to fetch data
}
public void Dispose()
{
connection.Dispose();
}
}
Usage:
using (IRepository repository = new SqlRepository(connectionString))
{
var item = repository.items;
}
Update
IRepository does implement IDisposable
如果你对这篇内容有疑问,欢迎到本站社区发帖提问 参与讨论,获取更多帮助,或者扫码二维码加入 Web 技术交流群。
绑定邮箱获取回复消息
由于您还没有绑定你的真实邮箱,如果其他用户或者作者回复了您的评论,将不能在第一时间通知您!
发布评论
评论(3)
不要在呼叫期间保持连接打开。您正在击败连接池。
如果您正在使用池化连接(如 sqlserver),它将池化并重用。只需在方法 a & 中打开和关闭即可b.
您可能会争辩说,如果调用者执行您使用一种方法调用所做的操作,那就没问题。但是,如果您在每个工作方法中使用带有 sqlconnection 的 {} (1) 代码会更简单,并且 (2) 您可以确保池不会被击败(这意味着当其他请求可以使用它时,您将保留项目从池中取出) 。
编辑:
根据评论添加伪。
该模式是有问题的,因为调用者可以这样做。
这会破坏服务器的可扩展性——相信我。我见过非常大的系统因此而陷入困境——通常是因为它们跨越 AT 端事务。
更好的模式:
现在,池是最有效的。我意识到问题在于一次性模式 - 是的,你可以做到。但是......
我不会让连接跨越存储库的生命周期。
Don't keep the connection open spanning calls. You're defeating connection pooling.
If you're working with a connection that's pooled (like sqlserver), it will pool and reuse. Just open and close within method a & b.
You could argue that if the caller does what you did with using with one method call it's fine. But if you do using {} with sqlconnection inside each worker method (1) the code will be simpler and (2) you're ensured the pooling wont be defeated (meaning your holding items out of the pooling when other requests could use it).
EDIT:
Adding pseudo based on comments.
The pattern is problematic because a caller can do.
That will kill the scalability of the server - trust me. I've seen very large systems get choked by this - usually because they're spanning AT side transactions.
A better pattern:
Now, the pool is most effective. I realize the question was on the disposable pattern - and yes you can do it. But ...
I would not let the connection span the lifetime of the repository.
如果你想这样做,请确保你实现了 IDisposable (我不知道你是否在 IRepository 接口上注意到了这一点),我会做类似的事情:
显然这里的 _context 是你的 SqlConnection。
但是 - 您确定要为每个存储库建立一个连接吗?跨越多个存储库的操作怎么样?
If you want to do it like that, ensure you implement IDisposable (I cant tell if you note this on your IRepository interface or not) and I'll do something like:
Obviously the _context here is your SqlConnection.
however - are you sure you want one connection per repository? What about operations spanning more than one repository?
假设
IRepository
继承自IDisposable
,只要您没有将SqlRepository
类的实例保持打开状态的时间超过其执行时间,那么您的实现就可以了。对数据库的“逻辑”查询序列。事实上,这个序列可能跨越多个方法调用,这不是问题。我不同意@bryanmac的回答:
假设您的方法调用序列属于在一起,并且您保持连接打开的时间不超过完成逻辑序列所需的时间,我看不出这会以任何方式破坏连接池。
不过有一条评论。您应该:
要么实现标准的
IDisposable
模式(使用可以在派生类中重写的protected void Dispose(bool dispose)
方法或者使您的类密封,在这种情况下您现有的
IDisposable
实现没问题。Assuming
IRepository
inherits fromIDisposable
, your implementation is fine provided you are not keeping an instance of yourSqlRepository
class open for longer than it takes to perform a 'logical' sequence of queries on the database. The fact that this sequence might span several method calls is not a problem.I disagree with @bryanmac's answer:
Provided your sequence of method calls belong together, and you don't keep the connection open for longer than it takes to complete the logical sequence, I don't see how this in any way defeats connection pooling.
One comment though. You should:
Either implement the standard
IDisposable
pattern (with aprotected void Dispose(bool disposing)
method that can be overridden in derived classesOr make your class sealed, in which case your existing
IDisposable
implementation is fine.