J'essaie d'obtenir une instance de DbContext (donc je peux faire un travail supplémentaire au démarrage avec lui), j'obtiens l'erreur suivante lorsque j'essaie d'obtenir une instance dans la méthode Configure:
System.InvalidOperationException: 'Impossible de résoudre le service de portée' MyApp.Data.MyDbContext 'du fournisseur racine.'
public void ConfigureServices(IServiceCollection services)
{
services.AddDbContext<MyDbContext>(
options => options.UseSqlServer(Configuration.GetConnectionString("MyDbContext")));
}
public void Configure(IApplicationBuilder app, IHostingEnvironment env)
{
var dbContext = app.ApplicationServices.GetService(typeof(MyDbContext)) as MyDbContext;
}
Je peux accéder à une instance de l'amende DbContext via le contrôleur, etc.
Le commentaire de Paul Hiles est correct mais cette méthode fonctionne mieux dans .NET Core 1.0.
Dans ASP.NET Core 2.0, c'est généralement une mauvaise idée d'exécuter une configuration de base de données dans Startup.cs
. En effet, si vous exécutez des migrations à partir de la CLI ou de Visual Studio, il exécutera tous les Startup.cs
et essayez d'exécuter votre configuration qui échouera. Bien sûr, si vous n'utilisez pas Entity-Framework, ce n'est pas un problème, mais ce n'est toujours pas la manière recommandée de le faire dans 2.0. Il est maintenant recommandé de le faire dans Program.cs
.
Par exemple, vous pouvez créer une méthode d'extension de IWebHost
qui exécutera toute configuration dont vous avez besoin.
public static IWebHost MigrateDatabase(this IWebHost webHost)
{
var serviceScopeFactory = (IServiceScopeFactory)webHost.Services.GetService(typeof(IServiceScopeFactory));
using (var scope = serviceScopeFactory.CreateScope())
{
var services = scope.ServiceProvider;
var dbContext = services.GetRequiredService<YourDbContext>();
dbContext.Database.Migrate();
}
return webHost;
}
Et puis dans Program.cs
vous pouvez ensuite appeler cette méthode avant de l'exécuter.
public static void Main(string[] args)
{
BuildWebHost(args)
.MigrateDatabase()
.Run();
}
Juste pour ajouter à @ Travis Boatman excellente réponse, la syntaxe préférée de la méthode Main
a légèrement modifiée à partir de Core 2.1 et la valeur par défaut Main
la méthode a désormais CreateWebHostBuilder
au lieu de BuildWebHost
.
Le code révisé pour appeler la méthode d'extension est indiqué ci-dessous.
NB: l'ordre est important ici, la méthode Build
renvoie un WebHost
, qui est ce que la méthode d'extension étend, vous devez donc appeler la méthode migrate après Build()
et avant Run()
):
public static void Main(string[] args)
{
CreateWebHostBuilder(args)
.Build()
.MigrateDatabase()
.Run();
}
Nous avons plus d'un DbContext
dans notre projet, j'ai donc changé la méthode d'extension en une méthode générique qui peut prendre n'importe quel type de DbContext
:
public static IWebHost MigrateDatabase<T>(this IWebHost webHost) where T:DbContext
{
var serviceScopeFactory = (IServiceScopeFactory)webHost
.Services.GetService(typeof(IServiceScopeFactory));
using (var scope = serviceScopeFactory.CreateScope())
{
var services = scope.ServiceProvider;
var dbContext = services.GetRequiredService<T>();
dbContext.Database.Migrate();
}
return webHost;
}
Vous pouvez ensuite chaîner les appels pour migrer les différents contextes:
CreateWebHostBuilder(args)
.Build()
.MigrateDatabase<ApiAuthDbContext>()
.MigrateDatabase<MainDbContext>()
.MigrateDatabase<SomeOtherDbContext>()
.Run();