在 LINQ-SQL 中,将 DataContext 包装为一个 using 语句 - 优点 缺点
有人可以从性能、内存使用、编码简易性、正确做法等因素方面阐述将 DataContext 包装在 using 语句中或不在 LINQ-SQL 中之间的优缺点吗?
更新:在一个特定的应用程序中,我经历过,如果没有将 DataContext 包装在 using 块中,内存使用量会不断增加,因为活动对象没有被释放以进行 GC。如下例所示,如果我持有对 q 对象列表的引用并访问 q 的实体,我将创建一个不为 GC 释放的对象图。
DataContext 使用
using (DBDataContext db = new DBDataContext())
{
var q =
from x in db.Tables
where x.Id == someId
select x;
return q.toList();
}
DataContext 而不使用 using 并保持活动状态,
DBDataContext db = new DBDataContext()
var q =
from x in db.Tables
where x.Id == someId
select x;
return q.toList();
谢谢。
Can someone pitch in their opinion about pros/cons between wrapping the DataContext in an using statement or not in LINQ-SQL in terms of factors as performance, memory usage, ease of coding, right thing to do etc.
Update: In one particular application, I experienced that, without wrapping the DataContext in using block, the amount of memory usage kept on increasing as the live objects were not released for GC. As in, in below example, if I hold the reference to List of q object and access entities of q, I create an object graph that is not released for GC.
DataContext with using
using (DBDataContext db = new DBDataContext())
{
var q =
from x in db.Tables
where x.Id == someId
select x;
return q.toList();
}
DataContext without using and kept alive
DBDataContext db = new DBDataContext()
var q =
from x in db.Tables
where x.Id == someId
select x;
return q.toList();
Thanks.
如果你对这篇内容有疑问,欢迎到本站社区发帖提问 参与讨论,获取更多帮助,或者扫码二维码加入 Web 技术交流群。
绑定邮箱获取回复消息
由于您还没有绑定你的真实邮箱,如果其他用户或者作者回复了您的评论,将不能在第一时间通知您!
发布评论
评论(5)
相对于其他事物,DataContext 的创建成本可能很高。但是,如果您完成了它并希望尽快关闭连接,这将做到这一点,并从上下文中释放所有缓存的结果。请记住,无论如何,您都会创建它,在这种情况下,您只是让垃圾收集器知道还有更多免费的东西可以删除。
DataContext 被设计为一个简短的 use 对象,使用它,完成工作单元,然后退出......这正是您使用 using 所做的事情。
所以优点:
缺点 - 更多代码?但这不应该成为一种威慑,您在这里正确地使用了
using
。看看微软的答案: http://social.msdn.microsoft.com/Forums/en-US/adodotnetentityframework/thread/2625b105-2cff-45ad-ba29-abdd763f74fe
如果您需要使用
using
/.Dispose()
:A DataContext can be expensive to create, relative to other things. However if you're done with it and want connections closed ASAP, this will do that, releasing any cached results from the context as well. Remember you're creating it no matter what, in this case you're just letting the garbage collector know there's more free stuff to get rid of.
DataContext is made to be a short use object, use it, get the unit of work done, get out...that's precisely what you're doing with a using.
So the advantages:
Downside - more code? But that shouldn't be a deterrent, you're using
using
properly here.Look here at the Microsoft answer: http://social.msdn.microsoft.com/Forums/en-US/adodotnetentityframework/thread/2625b105-2cff-45ad-ba29-abdd763f74fe
Short version of if you need to use
using
/.Dispose()
:嗯,这是一个
IDisposable
,所以我想这不是一个坏主意。 MSFT 的人员表示,他们使 DataContext 尽可能轻量级,以便您可以不计后果地创建它们,因此您可能不会获得太多好处......Well, It's an
IDisposable
, so I guess it's not a bad idea. The folks at MSFT have said that they made DataContexts as lightweight as possible so that you may create them with reckless abandon, so you're probably not gaining much though.....更不用说每个 DataContext 背后都是您从数据库请求的所有对象的身份映射(您不想保留它)。
DataContext 的整个理念是工作单元和乐观并发。
将其用于短期交易(仅提交一次)并处置。
不要忘记 dispose 的最好方法是使用 ()。
Not to mention that behind every DataContext is identity map of all objects you are asking from DB (you don’t want to keep this around).
Entire idea of DataContext is Unit Of Work with Optimistic Concurrency.
Use it for short transaction (one submit only) and dispose.
Best way to not forget dispose is using ().
我取决于你的数据层的复杂性。如果每个调用都是一个简单的单个查询,那么每个调用都可以像您的问题中那样包装在“使用”中,这样就可以了。
另一方面,如果您的数据层可以预期来自业务层的多个连续调用,那么您最终会为每个较大的调用序列重复创建/处置 DataContext。不理想。
我所做的是将数据层对象创建为 IDisposible。创建时,会创建 DataContext(或者实际上是在第一次调用方法后),并且当数据层对象释放时,它会关闭并释放 DataContext。
它看起来像这样:
I depends on the complexity of your Data Layer. If every call is a simple single query, then each call can be wrapped in the Using like in your question and that would be fine.
If, on the other hand, your Data Layer can expect multiple sequential calls from the Business Layer, the you'd wind up repeatedly creating/disposing the DataContext for each larger sequence of calls. not ideal.
What I've done is to create my Data Layer object as IDisposible. When it's created, the DataContext is created (or really, once the first call to a method is made), and when the Data Layer object disposes, it closes and disposes the DataContext.
here's what it looks like:
在一个特定的应用程序中,我发现,如果没有将
DataContext
包装在using
块中,内存使用量就会持续增加,因为活动对象没有被释放以进行 GC。如下例所示,如果我保存对List 对象的引用并访问
q
的实体,我将创建一个不会为 GC 释放的对象图。在这个示例中,我无法处置数据上下文,因为列表变量
qs
中的所有Table
实例 **共享相同的数据上下文。在Dispose()
之后,访问process(Table q)
中的实体会抛出 datacontext 已处置异常。对我来说,丑陋的克鲁格是在 foreach 循环之后删除 q 对象的所有实体引用。更好的方法当然是使用
using
语句。就我的经验而言,我会说使用
using
语句。In one particular application, I experienced that, without wrapping the
DataContext
inusing
block, the amount of memory usage kept on increasing as the live objects were not released for GC. As in, in below example, if I hold the reference toList<Table>
object and access entities ofq
, I create an object graph that is not released for GC.Given this example, I cannot dispose the datacontext because all the
Table
instances in list variableqs
**share the same datacontext. AfterDispose()
, accessing the entity inprocess(Table q)
throws a datacontext already disposed exception.The ugly kluge, for me, was to remove all the entity references for q objects after the foreach loop. The better way is to of course use the
using
statement.As far as my experience goes, I would say use the
using
statement.