2013-09-05 3 views
6

Ich entwickelte eine Webanwendung mit ASP.NET MVC 4 und SQL Server 2008, ich erstelle ContextManager-Klasse, um nur einen Datenbankkontext auf allen Seiten zu haben.DbContext wurde entfernt

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

Es funktioniert in den meisten Seiten, aber in Registrierungsseite etwas schief geht und mein Zusammenhang mit folgendem Fehler abgesetzt gegangen:

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

an der Linie _db.Contacts.Add(contact); Ich habe die Ausnahme .

Aber ohne ContextManager mit von

HotelContext _db = ContextManager.Current; 

ausgetauscht wurden durch:

HotelContext _db = new HotelContext(); 

das Problem gelöst wurde. Aber ich muss meinen eigenen ContextManager verwenden. Was ist das Problem?

Antwort

7

Ihr Kontext wurde an anderer Stelle entfernt (nicht im Code, den Sie angezeigt haben). Wenn Sie also von Ihrer Aktion aus auf Register zugreifen, wird die Ausnahme ausgelöst.

Eigentlich sollten Sie keinen statischen Singleton verwenden, um auf Ihren Kontext zuzugreifen. Instanziieren Sie für jede Anforderung eine neue DbContext Instanz. Siehe c# working with Entity Framework in a multi threaded server

+0

Das Problem tritt nach dem Erstellen des Benutzers und ich überprüft auch meine db, um sicher zu gehen, WebSecurity.CreateUserAndAccount ist erfolgreich, aber bei _db.Contacts.Add (Kontakt); Ich habe die Ausnahme. –

+1

@ ken2k, der ContextManager speichert den DbContext in HttpContext.Current.Items, so dass es eine neue Instanz pro Anfrage sein wird. – mendel

2

Sie sind wahrscheinlich "Lazy Loading" eine Navigationseigenschaft von User in Ihrer Registrierungsansicht. Stellen Sie sicher, dass Sie es mit Hilfe der Include Methode auf Ihrem DbSet umfassen, bevor es zu der Ansicht zu senden:

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

Auch teilen DbContext s mit einer statischen Eigenschaft kann zu unerwarteten Nebenwirkungen haben.

2

In meinem Fall rief meine GetAll-Methode die ToList() -Methode nach where-Klausel im Lambda-Ausdruck nicht auf. Nach der Verwendung von ToList() wurde mein Problem gelöst.

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

Früher hatte ich das gleiche Problem. Ich löste es so, wie es oben gesagt wurde. Instanziieren Sie eine neue Instanz Ihres Kontexts.

Versuchen Sie dies mit:

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

diese Weise ist es jedes Mal eine neue Instanz erstellt werden, werden Sie Ihren Code und Ihrem Kontext verwenden wird nicht entsorgt werden.