entity framework上下文是否应该使用陈述?
entity framework上下文对象实现了“释放对象上下文使用的资源”的Dispose()方法。 它究竟做了什么? 总是把它放到一个using {}语句中是不是一件坏事? 我已经看到使用和不使用using语句。
我特别要从WCF服务方法中使用EF上下文,创build上下文,执行一些linq并返回答案。
编辑:似乎我不是唯一一个想知道这个。 另一个问题是Dispose()方法中真正发生了什么。 有人说它closures连接,有些文章说不。 这是怎么回事?
如果你创build一个上下文,你必须稍后处理。 如果你应该使用using
语句,则取决于上下文的生存期。
-
如果您在方法中创build上下文并仅在此方法中使用上下文,那么您应该真正使用
using
语句,因为它使您无需任何其他代码即可处理exception。 -
如果您使用上下文的时间较长(即生命时间不受方法的执行时间限制),则不能使用
using
语句,而必须自己调用Dispose()
并注意始终调用它。
Dispose()
为对象上下文做些什么?
我没有看代码,但至less我预计它会closures与其底层套接字或传输机制使用的任何资源的数据库连接。
既然你不知道什么时候垃圾收集器处理一个项目,如果你知道什么时候完成了,那么总结一下在一个using块中实现IDisposable的对象总是很好的。
每个编程entity framework :“你可以显式地处理ObjectContext或者等待垃圾收集器来完成这个工作。
所以,简而言之,虽然using语句不是必需的,但最好的做法是如果您知道使用ObjectContext完成了,因为资源是立即释放的,而不是等待垃圾回收。
EF5和之前的版本
using { ... // connecction open here. ... context.Blogs.Add(blog); context.SaveChanges(); // query etc now opens and immediately closes ... context.Blogs.Add(blog); context.SaveChanges(); // query etc now opens and immediately closes }
EF6和以后的版本
using { // connecction open here. ... context.Blogs.Add(blog); context.SaveChanges(); // The underlying store connection remains open for the next operation ... context.Blogs.Add(blog); context.SaveChanges(); // The underlying store connection is still open } // The context is disposed – so now the underlying store connection is closed
参考: http : //msdn.microsoft.com/en-us/data/dn456849#open5
总是,如果你实例化一个实现了IDisposable的类,那么你负责调用Dispose。 除了一个例外,这意味着一个使用块。
在处理时,ObjectContext处理其他拥有的对象。
包括诸如包装实际数据库连接的EntityConnection之类的东西,即通常是SqlConnection。
所以'如果'SqlConnection是打开的,它将在你处理ObjectContext时closures。
我真的testing了ADO.net和EF v.6这个东西,并观察SQL表中的连接
select * from sys.dm_exec_connections
要testing的方法如下所示:
1)使用ADO.net
using(var Connection = new SqlConnection(conString)) { using (var command = new SqlCommand(queryString, Connection)) { Connection.Open(); command.ExecuteNonQueryReader(); throw new Exception() // Connections were closed after unit-test had been //finished. Expected behaviour } }
2)使用ADO.net
var Connection = new SqlConnection(conString); using (var command = new SqlCommand(queryString, Connection)) { Connection.Open(); command.ExecuteNonQueryReader(); throw new Exception() // Connections were NOT closed after unit-test had been finished finished. I closed them manually via SQL. Expected behaviour }
1)EF使用。
using (var ctx = new TestDBContext()) { ctx.Items.Add(item); ctx.SaveChanges(); throw new Exception() // Connections were closed, as expected. }
2)EF没有使用
var ctx = new TestDBContext(); ctx.Items.Add(item); ctx.SaveChanges(); throw new Exception() // Connections WERE successfully closed, as NOT expected.
我不知道为什么会这样,但EF自动closures连接。 另外所有使用EF的库和UnitOfWork的模式都不使用。 这对我来说很奇怪,因为DBContext是Disposabletypes,但这是事实。
也许在微软,他们做了一些新的处理?
我注意到(尽pipe只有一个应用程序),显式的处理是在应用程序代码之前捕获的mscorlib中引起线程中止exception,但至less在我的情况下导致了明显的性能下降。 对这个问题还没有做过任何重大的研究,但是如果你这样做的话可能值得考虑。 只要看你的DEBUG输出,看看你是否得到相同的结果。
如果Disposeclosures与数据库的连接,那么调用它是一个坏主意。 例如,在ADO.NET中,连接处于连接池中,并且在超时或应用程序池停止之前从不closures。