47430


ネットで見ると、

[code]

    DBContext db = new DBContexxt();
    
[/code]

の内容をControllerのアクション外に定義している場合とアクション内に定義している場合がありました。

アクション外では

[code]

    namespace crud.Controllers
    {
        public class HomeController : Controller
        {
            //context as db
            private MyContext db = new MyContext();
            ...
    
[/code]

といった感じです。

アクション内では

[code]

    [HTTPPost]
    public ActionResult Create(Human h)
    {
       using(DBContext db = new DBContext())
       {
        if (ModelState.IsValid)
          {
            db.Human.Add(h);
            db.SaveChanges();
            return RedirectToAction("Index");
          }
       }
    }
    
[/code]

HTTPPostのActionResultメソッド内で書かれている内容はPostの都度、DBに接続＋解除していますが、アクション外でContextを宣言している場合はいつ解除(Dispose)されているのでしょうか。

このあたりが明確に理解できていませんので、ご教授いただけると幸いです。


CC BY-SA 4.0
2018-08-10T16:00:57.260
47426
2018-08-10T21:14:33.123
2018-08-10T21:14:33.123
4236
12388
question
c# asp.net mvc entity-framework
ASP.NET MVCのController内でDBContextの宣言位置による接続解除の挙動


ASP.NET WebFormと異なり、ASP.NET
MVCでは状態を保持しません。このことはブラウザーからのリクエスト毎に`Controller`が作成・破棄されることを意味します。そのため`Controller`内に置かれた`DBContext`オブジェクトは`Controller`が破棄されたタイミングでどこからも参照されなくなり、GCにより適切なタイミングで破棄されます。  
つまり、`DBContext`オブジェクトはブラウザーからのリクエストとは同期しないが頻繁に生成・破棄が繰り返されている、となります。

さて、データベース接続についてですが、これは接続方法次第です。しかし、基本的に[Connection Pooling;
接続プール](https://docs.microsoft.com/ja-
jp/dotnet/framework/data/adonet/connection-
pooling)が有効となっているはずなので、`DBContext`オブジェクトの生存期間とデータベース接続の期間は同期していません。  
`DBContext`オブジェクトが破棄されたとしてもデータベース接続はプールに残されますし、`DBContext`オブジェクトはプールに残されているデータベース接続を再利用します。プールで長時間放置されたデータベース接続は自動的に切断されます。  
つまり、データベース接続は`DBContext`オブジェクトとは無関係に管理されている、となります。接続プールが無効化された場合、大変なことになるかもしれません。


CC BY-SA 4.0
2018-08-10T21:12:58.043
47430
2018-08-10T21:12:58.043
4236
47426
answer