Dbcontext has been disposed when using “using Statement”

天涯浪子 提交于 2020-07-10 04:43:29

问题


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:

  1. GetUserByEmailId is called, _instance is null, so it is initialized
  2. GetUserByEmailId is completed, and context is disposed. But the object still exists in _instance field
  3. UpdateUser is called, _instance is not null, so the old context is returned in using
  4. context.SaveChanges is 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

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