2013-09-05 117 views
6

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

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

它可以正常工作中大部分的网页,但在注册页面出现错误,我的背景下飘以下错误废黜:在该行_db.Contacts.Add(contact);

The operation cannot be completed because the DbContext has been disposed.

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

我得到异常。

,但没有使用ContextManager通过改变

HotelContext _db = ContextManager.Current; 

到:

HotelContext _db = new HotelContext(); 

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

回答

7

你的上下文已经被放置在其他地方(不在你显示的代码中),所以基本上当你从你的Register动作访问它时,它会抛出异常。

实际上,你不应该使用静态单例来访问你的上下文。 请为每个请求实例化一个新的DbContext实例。请参阅c# working with Entity Framework in a multi threaded server

+0

创建用户后,我也检查了我的数据库,确保WebSecurity.CreateUserAndAccount正在成功进行,但在_db.Contacts.Add(contact);我得到了例外。 –

+1

@ ken2k,ContextManager正在HttpContext.Current.Items中存储DbContext,因此它将成为每个请求的新实例。 – mendel

2

您可能在您的注册视图中“延迟加载”导航属性User。确保你使用你的DbSet它发送到视图前Include方法包括它:

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

此外,通过一个静态属性共享DbContext S可有意想不到的副作用。

2

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

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

我曾经有过同样的问题。正如上面所说,我解决了它的问题。实例化您的上下文的新实例。

尝试使用这样的:

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

这样,它会创建一个新的实例每次你用你的代码,你的背景下不会被布置。

相关问题