EntityFramework系列(三)---上下文線程內唯一
阿新 • • 發佈:2018-05-22
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系列(三)---上下文線程內唯一