使用"使用Statement"时已经处理了Dbcontext。

时间:2014-12-30 18:07:19

标签: c# entity-framework

错误讯息:

  

由于已经处理了dbcontext,因此无法完成操作。

在执行更新时,有人可以解释我的DbContext被处理的原因和位置吗?

上下文文件:

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; }
   }
}

业务逻辑:

    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);
        }
    }

单元测试:

    [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");
    }

谢谢。

2 个答案:

答案 0 :(得分:2)

第二次调用存储库上的方法时会将其释放。时间表就是这样:

  1. GetUserByEmailId被调用,_instance为空,因此它被初始化
  2. GetUserByEmailId已完成,并且已处理上下文。但该对象仍存在于_instance字段
  3. 中 调用
  4. UpdateUser_instance不为空,因此在using
  5. 中返回旧的上下文
  6. context.SaveChanges被调用,但由于已经处理了这个上下文对象,因此抛出异常
  7. 这通常是一个好主意,以避免像这样缓存数据库上下文。基本的经验法则是每单位工作一个上下文对象&#34;。您可以在thread(由Jon Skeet主演!)中找到更多有关原因的信息。

答案 1 :(得分:0)

using关键字是你具体说“当范围关闭时,在我传入的对象上调用.Dispose()”。这不是你想要的,因为你想一遍又一遍地重复使用这个对象。

删除使用,您将不再遇到此问题。 e.g。

var context = OnlineTestContext.GetInstance;
context.Entry(user).State = EntityState.Modified;
return context.SaveChanges();