2013-09-05 94 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 
      } 

這樣,它會創建一個新的實例每次你用你的代碼,你的背景下不會被佈置。

相關問題