1. 程式人生 > >EntityFramework系列(三)---上下文線程內唯一

EntityFramework系列(三)---上下文線程內唯一

ext.get 推薦 方法 隨著 ack 問題 IE public ==

為什麽要讓DbContext線程內唯一

  在使用EF的情況下,我們通常把SaveChange這個方法提到業務邏輯層,如果在用到DbContext的時候就new一個出來的話,不能保證同一個業務邏輯使用的是同一個上下文對象,不同的DbContext就不能對實體狀態進行有效的追蹤,可能造成數據混亂,一些EF對象獲得的數據可能已經被其他EF對象改變過,這就造成臟讀。

  使用單例模式可以有效避免臟讀的問題,但是DbContext對象不能被有效的釋放,如果無數請求使用同一個DbContext,這個DbContext對象容器就要追蹤無數個實體的狀態,內存壓力很大。保證在線程內對象唯一,對於每一個請求使用同一個上下文是一種折中的方法。通過微軟ASP機制線程相關的HttpContext對象以及CallContext對象。

  CallContext 的概念:是類似於方法調用的線程本地存儲區的專用集合對象,並提供對每個邏輯執行線程都唯一的數據槽。數據槽不在其他邏輯線程上的調用上下文之間共享。當 CallContext 沿執行代碼路徑往返傳播並且由該路徑中的各個對象檢查時,可將對象添加到其中。也就是說,當前線程對對象進行儲存到線程本地儲存區,對象隨著線程的銷毀而銷毀。

使用DbContext的代碼如下

 1   public class DbFactory
 2     {
 3          //callContext實現dbcontext唯一
 4          public static DbContext GetDbContext()
5 { 6 DbContext _context = CallContext.GetData("dbContext") as DbContext; 7 if (_context == null) 8 { 9 _context = new MyEntities(); 10 CallContext.SetData("dbContext", _context); 11 } 12 return
_context; 13 } 14 15 //在web環境下,在web環境下 16 //CallContext.HostContext as HttpContext==HttpContext.Current,線程不安全時可能為空,因此推薦第一種方式 17 public static DbContext GetDbContext2() 18 { 19 DbContext _context=HttpContext.Current.Items["dbContext"] as DbContext; 20 if (_context == null) 21 { 22 _context = new MyEntities(); 23 HttpContext.Current.Items["dbContext"]=_context; 24 } 25 return _context; 26 } 27 }

EntityFramework系列(三)---上下文線程內唯一