DbContext已经处理完毕

我使用ASP.NET MVC 4和SQL Server 2008开发了一个Web应用程序,我创建了ContextManager类,在所有页面中只有一个数据库上下文。

public static class ContextManager { public static HotelContext Current { get { var key = "Hotel_" + HttpContext.Current.GetHashCode().ToString("x") + Thread.CurrentContext.ContextID.ToString(); var context = HttpContext.Current.Items[key] as HotelContext; if (context == null) { context = new HotelContext(); HttpContext.Current.Items[key] = context; } return context; } } } 

它在大多数页面中都能正常工作,但是在注册页面出现了问题,我的上下文因以下错误而被废弃:

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

 public ActionResult Register ( RegisterModel model ) { if ( ModelState.IsValid ) { // Attempt to register the user try { WebSecurity.CreateUserAndAccount( model.UserName, model.Password, new { Email = model.Email, IsActive = true, Contact_Id = Contact.Unknown.Id } ); //Add Contact for this User. var contact = new Contact { Firstname = model.FirstName, LastName = model.Lastname }; _db.Contacts.Add( contact ); var user = _db.Users.First( u => u.Username == model.UserName ); user.Contact = contact; _db.SaveChanges(); WebSecurity.Login( model.UserName, model.Password ); 

_db.Contacts.Add( contact ); 我得到了例外。

但是不通过改变使用ContextManager

 HotelContext _db = ContextManager.Current; 

成:

 HotelContext _db = new HotelContext(); 

问题解决了。 但我需要使用自己的ContextManager。 问题是什么?

您的上下文已经被放置在其他位置(而不是在您显示的代码中),因此基本上当您从Register操作中访问它时,它会抛出exception。

实际上,您不应该使用静态单例来访问您的上下文。 为每个请求实例化一个新的DbContext实例 。 请参阅c#在multithreading服务器中使用Entity Framework

您可能在注册视图中“懒惰加载” User的导航属性。 在将其发送到视图之前,请确保在DbSet上使用Include方法Include它:

 _db.Users.Include(u => u.PropertyToInclude); 

此外,使用静态属性共享DbContext可能会产生意外的副作用。

在我的例子中,我的GetAll方法没有在lambda表达式中的where子句之后调用ToList()方法。 使用ToList()后我的问题解决了。

 Where(x => x.IsActive).ToList(); 

我曾经遇到过同样的问题。 我解决了它,如上所述。 实例化上下文的新实例。

试试这个:

  using (HotelContextProductStoreDB = new ProductStoreEntities()) { //your code } 

这样,每次使用代码时都会创建一个新实例,并且不会处理您的上下文。