0

I recently determined在.NET Core中使用Dependency Injected DbContext並使用異步等待調用沒有顯着的性能收益,而不是每次我想訪問數據庫時創建新的DbContext。爲什麼創建一個新的DbContext比Dependency Injected慢?

但現在我需要知道爲什麼。

我在.NET Core 1.1 API服務(控制器正在調用)中使用System.Diagnostics.Stopwatch進行了更細化的測試,其中只有在訪問數據庫時才運行秒錶。結果令人驚訝。

當使用標準的依賴注入上下文和異步/等待來電:

var task1 = _InjectedDbContext.Table1.FirstOrDefaultAsync(p => p.Id == SomeId); 
var task2 = _InjectedDbContext.Table2.Where(u => u.AnotherId == SomeOtherId).ToListAsync(); 

(var result1, var result2) = await (task1, task2).WhenAll(); 

各的DbContext查詢顯著花了不到100毫秒。

但是,使用這種方法時:

using (var context = new DbContext(_InjectedContextOptions.Options)) 
{ 
    var task1 = context.Table1.FirstOrDefaultAsync(p => p.Id == SomeId); 
    var task2 = context.Table2.Where(u => u.AnotherId == SomeOtherId).ToListAsync(); 

    (var result1, var result2) = await (task1, task2).WhenAll(); 
} 

每個的DbContext查詢少則100-230毫秒了。

僅供參考,這裏是我的DI設置在Startup.cs ConfigureServices代碼:

var connection = Configuration.GetConnectionString("mydb"); 
services.AddDbContext<MyDbContext>(options => options.UseSqlServer(connection)); 

這裏是我提供DbContextOptions因爲每當我創建一個新的DbContext一個單碼:

var dbContextOptions = new DbContextOptionsBuilder<MyDbContext>();   
dbContextOptions.UseSqlServer(Configuration.GetConnectionString("MyDb")); 
services.AddSingleton(dbContextOptions); 

我還確定,滯後不是由使用語句(這是一個非常快速的操作)中創建的DbContext而引起的。這裏發生了什麼?是否每次都試圖重新連接到數據庫?

+0

你是怎麼註冊你的DbContext的?因爲在應用程序的持續時間內,DI可能會在內存中保存DbContext的副本。該請求或一個調用基於您註冊DbContext的範圍。這將解釋性能增益。 –

+0

嗨,好問題。在兩種情況下,我都用DI的代碼更新了我的問題。生命期是在默認情況下:https://stackoverflow.com/questions/37507691/entity-framework-core-service-default-lifetime – starmandeluxe

+0

@RickvandenBosch:AddDbContext的默認註冊是有作用域的,所以它的解決每個請求,所以,應該沒關係。您是否偶然在單個請求期間創建大量的DbContext實例?通常DbContext會回收連接,但是如果你創建大量的連接,可能是它的原因 – Tseng

回答

0

您正在使用AddDbContext方法,用於您在第一個場景中使用的DbContext,它將DbContext作爲Scoped添加到服務中(如果我沒有錯誤的話)。 DbContext可能是因爲優化而添加服務時初始化的(這裏不確定)。對於第二種情況,您正在創建一個新的DbContext。除了創建DbContext之外,還有一些其他的東西需要完成。

this post兩者,這裏有一些提示,以「熱身」您的上下文:

  1. 使用緩存DB示範店
  2. 生成預編譯的意見
  3. 生成的預編譯的版本使用n-gen避免碰撞的實體框架

上面的提示表明,使用DbContext比使用DbContext更多,而不僅僅是新建一個並開始查詢。

+0

我同意你關於DI初始化的第一點。但我只是不確定這些優化:這不會幫助我在這裏介紹的兩種方法的性能,而不僅僅是新的上下文方法嗎?我更感興趣的是解釋兩者之間的差異,而不是提高EF性能的一般技巧。另外,我只做了DbContext的基準測試,這是一個非常微不足道的性能... – starmandeluxe

+0

嗨@starmandeluxe,正如我前面所說:我可以想象在AddDbContext方法中有一些優化,導致DI場景更快。這些提示僅用於顯示有提高性能的空間,這些可能已經在AddDbContext方法中實現,導致它比自己新建一個更快。 –

+0

@RickvandenBosch我會認爲問題在於事物是如何計時的。 – Mardoxx

相關問題