I recently determined que l'utilisation d'un DbContext Dependency Injected dans .NET Core et l'utilisation d'appels async await ne génèrent aucun gain de performance significatif par rapport à la création d'un nouveau DbContext chaque fois que je souhaite accéder à la base de données.Pourquoi créer un nouveau DbContext plus lent que celui de Dependency Injecté?
Mais maintenant j'ai besoin de savoir pourquoi.
J'ai fait un test beaucoup plus granulaire avec System.Diagnostics.Stopwatch dans mes services API .NET Core 1.1 (que le contrôleur appelle) dans lequel j'ai exécuté le chronomètre uniquement lors de l'accès à la base de données. Les résultats étaient surprenants.
Lorsque vous utilisez la norme contexte Injecté de dépendance et async/appels: attendent
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();
chaque requête DbContext a duré sensiblement moins de 100 ms.
Cependant, lorsque vous utilisez cette méthode:
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();
}
Chaque requête DbContext ont duré de 100-230 ms.
Pour votre information, voici mon code pour la configuration de DI dans Startup.cs ConfigureServices:
var connection = Configuration.GetConnectionString("mydb");
services.AddDbContext<MyDbContext>(options => options.UseSqlServer(connection));
Et voici mon code pour fournir les DbContextOptions comme singleton chaque fois que je crée une nouvelle DbContext:
var dbContextOptions = new DbContextOptionsBuilder<MyDbContext>();
dbContextOptions.UseSqlServer(Configuration.GetConnectionString("MyDb"));
services.AddSingleton(dbContextOptions);
J'ai également déterminé que le décalage n'est pas causé simplement par la création de DbContext dans l'instruction using (qui est une opération très rapide). Qu'est-ce qui se passe ici? Est-il essayer de se reconnecter à la DB à chaque fois ou quelque chose?
Comment avez-vous enregistré votre DbContext? Parce que le DI peut contenir une copie du DbContext en mémoire pour la durée de l'application. la demande ou un appel repose sur le périmètre que vous avez enregistré avec DbContext. Cela expliquerait le gain de performance. –
Salut, bonne question. J'ai mis à jour ma question avec le code pour le DI dans les deux cas. La durée de vie est à la valeur par défaut: https://stackoverflow.com/questions/37507691/entity-framework-core-service-default-lifetime – starmandeluxe
@RickvandenBosch: l'enregistrement par défaut pour AddDbContext est défini, donc il est résolu par requête, de sorte que shouldn ne sois pas.Avez-vous par hasard créer un grand nombre d'instances DbContext lors d'une seule requête? DbContext recycle généralement les connexions, mais si vous créez un grand nombre de connexions, cela peut être la raison pour cela – Tseng