问题
When should one call DbContext.dispose()
with entity framework?
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; }
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; }
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:
- When should I
Dispose()
of a context? - What should be the lifespan of my context?
Answers:
Never 1.
using
is an implicitDispose()
in atry-finally
block. A separateDispose
statement can be missed when an exception occurs earlier. Also, in most common cases, not callingDispose
at all (either implicitly or explicitly) isn't harmful.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