问题
Error message:
The operation cannot be completed because the dbcontext has been disposed.
Can somebody explain why and where my DbContext is getting disposed while I perform the update?
Context file:
using System.Data.Entity;
namespace OnlineTest
{
internal class OnlineTestContext : DbContext
{
private OnlineTestContext() : base("name=OnlineTest")
{
}
private static OnlineTestContext _instance;
public static OnlineTestContext GetInstance
{
get
{
if (_instance == null)
{
_instance = new OnlineTestContext();
}
return _instance;
}
}
public DbSet<User> Users { get; set; }
}
}
Business logic:
public int UpdateUser(User user)
{
user.ModifiedOn = DateTime.Now;
using (var context = OnlineTestContext.GetInstance)
{
context.Entry(user).State = EntityState.Modified;
return context.SaveChanges();
}
}
public User GetUserByEmailId(string emailId)
{
using (var context = OnlineTestContext.GetInstance)
{
return context.Users.First(u => u.EmailId == emailId);
}
}
Unit test:
[TestMethod]
public void UpdateUserUnitTest()
{
User user = onlineTestBusinessLogic.GetUserByEmailId("test@test");
user.PhoneNumber = "+91 1234567890";
int changes = onlineTestBusinessLogic.UpdateUser(user);
User Modifieduser = onlineTestBusinessLogic.GetUserByEmailId("test@test");
Assert.AreEqual(Modifieduser.PhoneNumber, "+91 0987654321");
}
Thank you.
回答1:
It is disposed by the second time you call a method on a repository. A timeline is like that:
GetUserByEmailIdis called,_instanceis null, so it is initializedGetUserByEmailIdis completed, and context is disposed. But the object still exists in_instancefieldUpdateUseris called,_instanceis not null, so the old context is returned inusingcontext.SaveChangesis called, but since this object of context is already disposed, the exception is thrown
This is generally a good idea to avoid caching db context like this. Basic rule of thumb is "one context object per unit of work". You can find some more information about why is it so in this thread (starring Jon Skeet!).
回答2:
The using keyword is you specifically saying "when the scope closes, call .Dispose() on the object I passed in". Which is not what you want, because you want to re-use the object over and over.
Remove the using and you will get stop getting this issue. e.g.
var context = OnlineTestContext.GetInstance;
context.Entry(user).State = EntityState.Modified;
return context.SaveChanges();
来源:https://stackoverflow.com/questions/27710341/dbcontext-has-been-disposed-when-using-using-statement