C# 实体框架上下文是否应该放入 using 语句?

声明:本页面是StackOverFlow热门问题的中英对照翻译,遵循CC BY-SA 4.0协议,如果您需要使用它,必须同样遵循CC BY-SA许可,注明原文地址和作者信息,同时你必须将它归于原作者(不是我):StackOverFlow 原文地址: http://stackoverflow.com/questions/824330/
Warning: these are provided under cc-by-sa 4.0 license. You are free to use/share it, But you must attribute it to the original authors (not me): StackOverFlow

提示:将鼠标放在中文语句上可以显示对应的英文。显示中英文
时间:2020-08-05 03:05:08  来源:igfitidea点击:

Should Entity Framework Context be Put into Using Statement?

c#entity-framework

提问by Johan Danforth

The Entity Framework context object implements a Dispose() method which "Releases the resources used by the object context". What does it do really? Could it be a bad thing to always put it into a using {} statement? I've seen it being used both with and without the using statement.

实体框架上下文对象实现了“释放对象上下文使用的资源”的 Dispose() 方法。它到底有什么作用?总是把它放在 using {} 语句中会不会是件坏事?我已经看到它在使用和不使用 using 语句时都被使用。

I'm specifically going to use the EF context from within a WCF service method, create the context, do some linq and return the answer.

我将专门从 WCF 服务方法中使用 EF 上下文,创建上下文,执行一些 linq 并返回答案。

EDIT:Seems that I'm not the only one wondering about this. Another question is what's really happening inside the Dispose() method. Some say it closes connections, and some articles says not. What's the deal?

编辑:似乎我不是唯一对此感到疑惑的人。另一个问题是 Dispose() 方法内部真正发生了什么。有人说它会关闭连接,而有些文章则说不会。这是怎么回事?

采纳答案by Daniel Brückner

If you create a context, you must dispose it later. If you should use the usingstatement depends on the life time of the context.

如果您创建了上下文,则必须稍后处置它。是否应该使用using语句取决于上下文的生命周期。

  1. If you create the context in a method and use it only within this method, you should really use the usingstatement because it gives you the exception handling without any additional code.

  2. If you use the context for a longer period - that is the life time is not bound by the execution time of a method - you cannot use the usingstatement and you have to call Dispose()yourself and take care that you always call it.

  1. 如果您在方法中创建上下文并仅在该方法中使用它,您应该真正使用该using语句,因为它为您提供了异常处理,而无需任何额外的代码。

  2. 如果您使用上下文的时间更长 - 即生命周期不受方法执行时间的限制 - 您不能使用该using语句,您必须调用Dispose()自己并注意始终调用它。

What does Dispose()do for an object context?

是什么Dispose()为对象范围内呢?

I did not look at the code, but at least I exspect it to close the database connection with its underlying sockets or whatever resources the transport mechanism used.

我没有看代码,但至少我希望它关闭与其底层套接字或传输机制使用的任何资源的数据库连接。

回答by John Saunders

Always, if you instantiate a class that implements IDisposable, then you are responsible for calling Dispose on it. In all but one case, this means a usingblock.

始终,如果您实例化一个实现 IDisposable 的类,那么您有责任在其上调用 Dispose。除了一种情况外,这意味着使用块。

回答by ullmark

Since you don't know when the garbage collector disposes an item, it's always good to wrap up objects that implement IDisposable in a using-blockif you know when you're done with it.

由于您不知道垃圾收集器何时处理一个项目,如果您知道何时处理完,最好将实现 IDisposable 的对象包装在using 块中

回答by Alex James

When you dispose, the ObjectContext disposes other owned objects.

处置时,ObjectContext 处置其他拥有的对象。

Including things like the EntityConnection which wraps the actual database connection, i.e. generally a SqlConnection.

包括诸如包装实际数据库连接的 EntityConnection 之类的东西,即通常是 SqlConnection。

So 'if' the SqlConnection is open it will be closed when you dispose the ObjectContext.

因此,“如果”SqlConnection 处于打开状态,则在您处置 ObjectContext 时它将关闭。

回答by Cory House

Per Progamming Entity Framework: "You can either explicitly dispose the ObjectContext or wait for the garbage collector to do the job."

每个编程实体框架:“您可以显式处理 ObjectContext 或等待垃圾收集器完成这项工作。”

So in short, while the using statement isn't required, it's best practice if you know you're done using the ObjectContext since the resource is freed up immediately instead of waiting for garbage collection.

所以简而言之,虽然 using 语句不是必需的,但最好的做法是,如果您知道已经完成了 ObjectContext 的使用,因为资源会立即被释放,而不是等待垃圾回收。

回答by Lewis Tatham

I have noticed (although in only one application) that the explicit disposal was causing thread abort exceptions in mscorlib which are caught before the application code, but at least in my case resulting in a noticeable performance hit. Haven't done any significant research on the issue, but probably something worth consideration if you are doing this. Just watch your DEBUG output to see if you are getting the same result.

我注意到(尽管仅在一个应用程序中)显式处理导致 mscorlib 中的线程中止异常,这些异常在应用程序代码之前被捕获,但至少在我的情况下导致明显的性能下降。尚未对此问题进行任何重大研究,但如果您正在这样做,可能值得考虑。只需观察您的 DEBUG 输出,看看您是否得到相同的结果。

回答by Ilya

If Dispose closes connection to DB it is a bad idea to call it. For example in ADO.NET connections are in connection pool and never be closed before timeout or application pool stop.

如果 Dispose 关闭与 DB 的连接,则调用它是个坏主意。例如,在 ADO.NET 中,连接在连接池中,并且在超时或应用程序池停止之前永远不会关闭。

回答by Artem G

I realy tested this thing for both ADO.net and EF v.6 and watched connections in SQL table

我真的为 ADO.net 和 EF v.6 测试了这个东西,并观察了 SQL 表中的连接

select * from sys.dm_exec_connections

Methods to be tested looked like this:

要测试的方法如下所示:

1) ADO.net with using

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 withour using

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 with using.

1)EF与使用。

 using (var ctx = new TestDBContext())
    {
        ctx.Items.Add(item);
        ctx.SaveChanges();
        throw new Exception() // Connections were closed, as expected.

     }

2) EF without using

2) EF 不使用

 var ctx = new TestDBContext();             
 ctx.Items.Add(item);
 ctx.SaveChanges();
 throw new Exception() // Connections WERE successfully closed, as NOT expected.

I don't know why is it so, but EF automatically closed connections. Also All the patterns of repository and UnitOfWork which use EF don't use using. It's very strange for me, because DBContext is Disposable type, but it's a fact.

我不知道为什么会这样,但是EF自动关闭了连接。此外,所有使用 EF 的存储库和 UnitOfWork 模式都不使用 using。对我来说很奇怪,因为 DBContext 是 Disposable 类型,但这是事实。

Maybe in Microsoft they did something new for handling?

也许在微软他们做了一些新的处理?

回答by user3556898

EF5 and before version

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 and after version

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

Reference: http://msdn.microsoft.com/en-us/data/dn456849#open5

参考:http: //msdn.microsoft.com/en-us/data/dn456849#open5