本節咱們來探討到底需不須要在鏈接字符串上加上MultipleActiveResultSets = true ?,若您有更深層次的理解歡迎留下您的腳印。數據庫
不少童鞋遇到以下圖中錯誤就立馬想到在鏈接字符串上加上 MultipleActiveResultSets = true ,可是這樣真的是最終解決方案麼?安全
下面咱們來看一段在EntityFramework 6.x中的代碼,演示如上問題的出現。學習
using (var ctx = new EfDbContext()) { ctx.Database.Log = Console.WriteLine; var customers = ctx.Customers; foreach (var customer in customers) { ctx.Entry(customer).Collection(d => d.Orders).Load(); } };
當您在EntityFramework 6.x中運行上述代碼就會拋出如上圖異常(不要關心上述代碼是否合理,或許您可能說直接使用顯式加載對吧,如上代碼旨在引出問題)。而後咱們在鏈接字符串上以下加上一句就能夠解決問題。spa
connectionString="Data Source=WANGPENG;Initial Catalog=EntityFramework6;Integrated Security=true;MultipleActiveResultSets=True;"
咱們知道MultipleActiveResultSets即MARS在SQL Server2005中被引入,意爲單鏈接多請求,可是它非線程安全,在我看來這個特性在ADO.NET中可能很是適用,可是在EntityFramework 6.x中做用不大,雖然如上能夠從數據庫鏈接層面來解決問題,大部分這種狀況的出現仍是由於代碼寫的有問題,咱們直接調用ToList便可,以下:線程
using (var ctx = new EfDbContext()) { ctx.Database.Log = Console.WriteLine; var customers = ctx.Customers.ToList(); foreach (var customer in customers) { ctx.Entry(customer).Collection(d => d.Orders).Load(); } };
咱們知道ToList是最終翻譯成SQL語句請求數據庫返回對應數據,即經過ToList既能夠打開鏈接也能夠關閉鏈接,當咱們不用ToList時,此時打開了一個鏈接,同時已經有了一個DataReader,接下來遍歷時則再會在Command上打開一個DataReader加載Orders,此時就會拋出第一個DataReader未關閉的狀況,大部分出現這樣的同樣咱們均可以經過ToList來解決,固然也能夠用延遲加載(關於EF 6.x中延遲加載請謹慎適用,我在個人書中《你必須掌握的EntityFramework 6.x與Core 2.0》中也有講到,除非您明確本身會正確使用)和顯式加載來解決。那在EntityFramework Core中是否運行上述一樣代碼會拋出異常,而後咱們須要在鏈接字符串上加上此特性呢?咱們來看看。翻譯
using (var context = new EFCoreDbContext()) { var blogs = context.Blogs; foreach (var blog in blogs) { context.Entry(blog).Collection(p => p.Posts).Load(); } }
經過如上圖咱們知道徹底不會如EntityFramework 6.x中拋出異常,這點有所不一樣。大部分狀況下,出現如上異常或許多是代碼寫的問題,不必定非得要加上 MultipleActiveResultSets=True;code
本文沒有深刻探討文章標題,若您有拋出如上異常非得加上MultipleActiveResultSets=True才能解決問題,請留下您的評論,讓我繼續深刻學習,在此表示感謝。接下來我會繼續探討和對比EntityFramework 6.x和EntityFramework Core中鮮爲人知的祕密,同時也會陸續更新EF Core 2.1並深刻探討。htm