问题
I recently determined that there are no significant performance gains from using a Dependency Injected DbContext in .NET Core and using async await calls as opposed to creating a new DbContext every time I want to access the DB.
But now I need to know why.
I did a much more granular test with System.Diagnostics.Stopwatch in my .NET Core 1.1 API services (which the controller is calling) in which I ran the stopwatch only when accessing the DB. The results were surprising.
When using the standard Dependency Injected context and async/await calls:
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();
each DbContext query took significantly less than 100 ms.
However, when using this method:
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();
}
Each DbContext query took anywhere from 100-230 ms.
FYI, here is my code for the DI setup in Startup.cs ConfigureServices:
var connection = Configuration.GetConnectionString("mydb");
services.AddDbContext<MyDbContext>(options => options.UseSqlServer(connection));
And here is my code for providing the DbContextOptions as a singleton whenever I create a new DbContext:
var dbContextOptions = new DbContextOptionsBuilder<MyDbContext>();
dbContextOptions.UseSqlServer(Configuration.GetConnectionString("MyDb"));
services.AddSingleton(dbContextOptions);
I also determined that the lag is not caused by simply the creation of the DbContext in the using statement (which is a very fast operation). What is going on here? Is it trying to re-connect to the DB every time or something?
回答1:
You're using the AddDbContext method, for the DbContext you use in the first scenario, which adds the DbContext to services as Scoped (if I'm not mistaking). The DbContext is probably initialized as soon as the service is added because of optimization (not sure here). For the second case you're creating a new DbContext. Apart from the DbContext creation there's also some other stuff that needs to be done.
Taken from this post, here are some tips to 'warm-up' your context:
- Using a cached DB model store
- Generate pre-compiled views
- Generate pre-compiled version of entityframework using n-gen to avoid jitting
The tips above indicate there's more to using a DbContext than 'just' newing one and start querying.
来源:https://stackoverflow.com/questions/44237272/why-is-creating-a-new-dbcontext-slower-than-a-dependency-injected-one