C#上下文管理

你的笑猶如初夏的陽光發表於2018-11-14

介紹:上下文的宣告週期開始於例項化,結束於垃圾回收器回收並釋放

現有流行方法使用using來操作上下文(try/finally)

   在使用上下文的過程中謹記一個原則:一個請求對應一個上下文

   下面簡單介紹三種使用上下文的方式

    1、Using Patten

      優點:自動釋放上下文

      缺點:不能在應用程式中共享上下文,程式碼複用性不高 

Using(var conn=new DbContent)
{
  ...
}

    2、DisPose Pattern

      優點:當請求執行完成之後會自動釋放上下文,

      缺點:很難保證共享上下文,需要所有開發者使用DisPose模式

public class EntityController:Controller{
    private EbDbContent _content;
    public BlogController()
    {
    _content=new EbDbContent();
    }
    Protected override void Dispose(bool disposing)
    {
    if(disposing)
    {
    _context.Dispose();
    }
     Vase.DisPose(disposing);
    }
}

  3、Dependency Injection

     優點:通過依賴注入能夠減輕控制器例項化上下文的負擔,不需要擔心上下文生命週期何時結束

public class EntityController:ontroller
{
 private EFDbContext _context;
 public BlogController(EFDbContext context)
 {
 _context=context
 }
}

     

生命週期追溯

      上下文例項實現了工作單元模式,

      工作單元模式:用於維護受業務事務的影響,並協調寫入資料庫的變更和解決併發問題。

      管理上下文例項的生命週期獨立於業務事務的宣告週期,將上下文的宣告週期和業務事務的宣告週期隔離開來

      1、效能考慮:每個上下文例項都維護著從資料庫中所有實體載入中的一級快取,無論何時需要巡查資料,預設情況需要從資料庫中獲取資料,但是此時將試圖從一級快取中獲取資料。由於一級快取的存在,在跨多個業務事務中使用相同上下文例項將減少和資料庫互動的次數

     2.延遲載入。如果服務返回的是poco實體而非經過DTO轉換過夠的實體,我們希望在這些實體上使用延遲載入,檢索出的所有實體的上下文例項的生命週期將超出業務事務的生命週期的範圍。

     上下文的宣告週期可以獨立於業務事務的宣告週期

保持上下文的生命週期很短暫,如果過長,在多個業務事務中會使得一級快取不會是最新的,從而導致併發問題。

      不能夠在多執行緒中訪問上下文,會造成多次查詢通過相同的資料庫連線同事併發返回,也會破壞通過上下文維護實體的變更追蹤和工作單元的一級快取。

      如果在多執行緒中使用資料庫連結,必須保證每個上下文的連結都是獨立的。

      EF6中支援在多執行緒中查詢一次,如果查詢多次將丟擲NotSupportedException的異常

      可以通過

       1.DbSet<T>.ToListAsync()

       2.FirstOrDefaultAsync()啟動多個查詢

async Task MultpleAsyncQuery()
{
    Using(var conn=new DbContent)
    {
          List<Task> task=new List<task>
          {
           var alltask=MultpleAsyncQuery();
           await allTasks;
          }
    }
}

解決上述問題的辦法:

       1:在多個非同步查詢中使用awit關鍵字

       2:對每個非同步查詢操作使用不同的上下文派生類例項,在EF6中,非同步查詢功能支援非同步程式設計模型,但是不支援並行

     資料來自書籍《你必須掌握的EntityFramework 6.x與.ne core 2.0》

     本人第一次部落格,如果有問題,請大佬們及時指出,

 

 

 

相關文章