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 }
这样,每次使用代码时都会创建一个新实例,并且不会处理您的上下文。