2013-09-05 23 views
6

ASP.NET MVC 4とSQL Server 2008でWebアプリケーションを開発しましたが、ContextManagerクラスを作成して、すべてのページに1つのデータベースコンテキストしか持たないようにしました。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); 

しかしに

HotelContext _db = ContextManager.Current; 

を変更することにより、ContextManagerを使用せず:

HotelContext _db = new HotelContext(); 

問題が解消しました。しかし私は私自身のContextManagerを使う必要があります。何が問題ですか?

答えて

7

コンテキストは、表示されているコードではなく、他の場所に配置されているため、基本的にはRegisterアクションからアクセスすると、例外がスローされます。

実際には、自分のコンテキストにアクセスするために静的なシングルトンを使用しないでください。 ごとに新しいDbContextインスタンスをインスタンス化します。 c# working with Entity Framework in a multi threaded server

+0

ユーザーを作成した後に問題が発生し、私のdbも確かめるためにWebSecurity.CreateUserAndAccountが正常に処理されていますが、_db.Contacts.Add(contact)で処理されています。私は例外がある。 –

+1

@ ken2kの場合、ContextManagerはHttpContext.Current.ItemsにDbContextを格納しているので、リクエストごとに新しいインスタンスになります。 – mendel

2

登録ビューでナビゲーションプロパティー「User」を「遅延読み込み」している可能性があります。ビューに送信する前に、あなたのDbSetIncludeメソッドを使用して、あなたはそれを含めることを確認してください:

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

また、静的プロパティとDbContext Sを共有し、予期せぬ副作用を有することができます。

2

私の場合、GetAllメソッドはラムダ式のwhere節の後にToList()メソッドを呼び出すことができませんでした。 ToList()を使用した後、私の問題は解決されました。

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

以前は同じ問題がありました。私は上記のようにそれを解決しました。コンテキストの新しいインスタンスをインスタンス化します。

は、これを使用してみてください:

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

あなたのコードとあなたのコンテキストを使用するたびに新しいインスタンスを作成することがあります。この方法で配置されることはありません。

関連する問題