Entity Framework and calling context.dispose()

久未见 提交于 2019-11-26 03:54:48

问题


When should one call DbContext.dispose() with entity framework?

  1. Is this imaginary method bad?

    public static string GetName(string userId)
    {
        var context = new DomainDbContext();
        var userName = context.UserNameItems.FirstOrDefault(x => x.UserId == userId);
        context.Dispose();
        return userName;
    }
    
  2. Is this better?

    public static string GetName(string userId)
    {
        string userName;
        using(var context = new DomainDbContext()) {
            userName = context.UserNameItems.FirstOrDefault(x => x.UserId == userId);
            context.Dispose();
        }
        return userName;
    }
    
  3. Is this even better, that is, should one NOT call context.Dispose() when using using()?

    public static string GetName(string userId)
    {
        string userName;
        using(var context = new DomainDbContext()) {
            userName = context.UserNameItems.FirstOrDefault(x => x.UserId == userId);
        }
        return userName;
    }
    

回答1:


In fact this is two questions in one:

  1. When should I Dispose() of a context?
  2. What should be the lifespan of my context?

Answers:

  1. Never 1. using is an implicit Dispose() in a try-finally block. A separate Dispose statement can be missed when an exception occurs earlier. Also, in most common cases, not calling Dispose at all (either implicitly or explicitly) isn't harmful.

  2. See e.g. Entity Framework 4 - lifespan/scope of context in a winform application. In short: lifespan should be "short", static context is bad.


1 As some people commented, an exception to this rule is when a context is part of a component that implements IDisposable itself and shares its life cycle. In that case you'd call context.Dispose() in the Dispose method of the component.




回答2:


I followed some good tutorials to use EF and they don't dispose the context.

I was a bit curious about that and I noticed that even the well respected Microsoft VIP don't dispose the context. I found that you don't have to dispose the dbContext in normal situation.

If you want more information, you can read this blog post that summarizes why.




回答3:


Better still:

public static string GetName(string userId)
{
    using (var context = new DomainDbContext()) {
        return context.UserNameItems.FirstOrDefault(x => x.UserId == userId);
    }
}

No need to return the result from outside the using scope; just return it immediately and you'll still get the desired disposal behavior.




回答4:


You can define your database context as a class field, and implement IDisposable. Something like below:

public class MyCoolDBManager : IDisposable
{
    // Define the context here.
    private DomainDbContext _db;

    // Constructor.
    public MyCoolDBManager()
    {
        // Create a new instance of the context.
        _db = new DomainDbContext();
    }

    // Your method.
    public string GetName(string userId)
    {           
        string userName = _db.UserNameItems.FirstOrDefault(x => x.UserId == userId);

        return userName;
    } 

    // Implement dispose method.
    // NOTE: It is better to follow the Dispose pattern.
    public void Dispose()
    {
         _db.dispose();
         _db = null;
    }
}



回答5:


As Daniel mentioned, you don't have to dispose the dbContext.

From the article:

Even though it does implement IDisposable, it only implements it so you can call Dispose as a safeguard in some special cases. By default DbContext automatically manages the connection for you.

So:

public static string GetName(string userId) =>
    new DomainDbContext().UserNameItems.FirstOrDefault(x => x.UserId == userId);


来源:https://stackoverflow.com/questions/15666824/entity-framework-and-calling-context-dispose

易学教程内所有资源均来自网络或用户发布的内容,如有违反法律规定的内容欢迎反馈
该文章没有解决你所遇到的问题?点击提问,说说你的问题,让更多的人一起探讨吧!