我的数据库连接是否关闭? (Linq to Sql)
Posted
tags:
篇首语:本文由小常识网(cha138.com)小编为大家整理,主要介绍了我的数据库连接是否关闭? (Linq to Sql)相关的知识,希望对你有一定的参考价值。
我正在使用Linq to SQL并在博客文章中阅读有关尽快关闭数据库连接的信息。作为一个例子,他们展示了一个变量被转换为一个列表(使用.ToList())而不是实际返回Linq查询。我有以下代码:
public static bool HasPassword(string userId)
{
ProjDataContext db = new ProjDataContext();
bool hasPassword = (from p in db.tblSpecUser
where p.UserID == userId
select p.HasPassword).FirstOrDefault();
return hasPassword;
}
这个查询好吗?或者数据库连接是否保持打开的时间超过必要的时间?
谢谢你的任何建议
连接将自动管理。但是,有一些(或至少可以像评论所示)与DataContext相关的附加资源。在垃圾收集器销毁DataContext之前,不会释放这些资源。因此,通常最好确保在不再需要DataContext时调用dispose。
using (ProjDataContext db = new ProjDataContext()) {
bool hasPassword = (from p in db.tblSpecUser
where p.UserID == userId
select p.HasPassword).FirstOrDefault();
return hasPassword;
}
这里确保在使用块退出时调用db.Dispose()
,从而明确地关闭连接。
编辑:在讨论之后,我自己查看了DataContext配置(也使用了Reflector),并找到了从DataContext.Dispose
调用的以下代码(FW 3.5):
protected virtual void Dispose(bool disposing)
{
if (disposing)
{
if (this.provider != null)
{
this.provider.Dispose();
this.provider = null;
}
this.services = null;
this.tables = null;
this.loadOptions = null;
}
}
所以有资源被释放:
- 提供者可能持有
DbConnection
,日志(TextWriter
)和DbTransaction
。 CommonDataServices
。- 表字典。
LoadOptions
。
提供者可能拥有需要处置的资源(DbConnection
和DbTransaction
)。此外,可能必须处理日志的TextWriter
,这取决于用户分配给TextWriter
的日志记录机制的DataContext
的实例,例如,然后自动关闭的FileWriter。
其他属性保持,据我所知 - 没有太多细节 - 只有内存,但这也可以通过dispose方法用于垃圾收集,但是,它确定何时内存实际被释放。
所以,最后我完全赞同casparOne的声明:
通常,共享像这样的数据访问资源是个坏主意。
您应该创建资源来访问数据库,执行操作,然后在完成后处置它们。
从实施的角度来看,不,你没有什么可担心的。但是,这不是由于查询,而是由于DataContext本身的管理。
DataContext类实现了IDisposable接口,因此您应该在完成DataContext实现后调用Dispose。
不幸的是,这也是非常糟糕的做法。您应始终对合同进行编码,而不是实施。因为DataContext实现了IDisposable,所以你应该关闭它,即使你知道它什么也不做,因为在将来的实现中它可以绝对改变。
此外,如果你切换到另一个LINQ提供程序,比如LINQ-to-Entities,那么你必须在完成后调用Dispose,因为ObjectContext实例中的数据库连接的生命周期(也实现了IDisposable)是非常不同的,并且调用Dispose对这些数据库连接有影响。
所有这一切,你都有更大的关注。如果您正在共享一个DataContext,则存在跟踪太多对象的风险。除非您将ObjectTrackingEnabled property设置为false,否则DataContext将跟踪通过它选择的每个对象。如果您在应用程序的生命周期内没有执行任何更新操作(或者即使您没有),则专用于共享DataContext上的对象跟踪的资源数量可能会变得相当大。
使用其他数据库技术(例如classes in the System.Data.SqlClient namespace)的规则仍然适用。
通常,共享像这样的数据访问资源是个坏主意。
您应该创建资源来访问数据库,执行操作,然后在完成后处置它们。
使用Linq-To-SQL,您通常不需要担心专门打开和关闭作为上下文对象一部分的连接(在您的示例中为db)。关于你必须专门做这件事的唯一时间是你通过上下文对象发送直接SQL调用,而不是使用Linq。
使用L2S,您通常希望创建上下文对象,执行工作单元,然后尽快处理对象。您的代码示例对我来说很好。
我认为使用using语句是一种很好的做法。但我认为您的查询没有任何不妥之处。
public static bool HasPassword(string userId)
{
using(var db = new ProjDataContext())
{
bool hasPassword = (from p in db.tblSpecUser
where p.UserID == userId
select p.HasPassword).FirstOrDefault();
return hasPassword;
}
}
数据库连接将在db对象不再存在(已处置)或显式关闭后立即关闭。在您的样本中,它将(迟早)收集垃圾。
以上是关于我的数据库连接是否关闭? (Linq to Sql)的主要内容,如果未能解决你的问题,请参考以下文章