Ho provato a IConfiguration
nella migrazione (nel costruttore) e ho ottenuto un'eccezione: "Nessun costruttore senza parametri definito per questo oggetto".
qualche soluzione?
non è possibile, le migrazioni devono essere in grado di funzionare al di fuori del contesto dell'applicazione.
Poiché lo strumento da riga di comando Entity-framework analizza il codice ma non esegue la classe startup.cs.
Inoltre, non è consigliabile. le tue migrazioni dovrebbero essere semplici e non dipendere da nulla. se lo fosse, potrebbe portare a effetti collaterali di runtime importanti in cui la configurazione mancante potrebbe portare alla mancata produzione di tabelle o colonne.
Se comporta un sacco di piccole / uguali / modifiche manuali. Il modo migliore è generare il tuo file di migrazione. Perché? In questo modo la tua migrazione sarà deterministica: sai quale sarà il risultato. Se una linea nella tua migrazione fallisce, è semplice e chiaro perché sia e facilmente (e) risolvibile.
C'è un modo per fare quello che vuoi fare. Nel mio scenario, vorrei utilizzare il nome del database nella stringa di connessione tramite DbContext. Viene utilizzato il core EF 2.1.1. Il codice viene modificato da qui
Creare un servizio personalizzato di MigrationsAssembly
using Microsoft.EntityFrameworkCore;
using Microsoft.EntityFrameworkCore.Diagnostics;
using Microsoft.EntityFrameworkCore.Infrastructure;
using Microsoft.EntityFrameworkCore.Internal;
using Microsoft.EntityFrameworkCore.Migrations;
using Microsoft.EntityFrameworkCore.Migrations.Internal;
using System;
using System.Reflection;
public class ContextAwareMigrationsAssembly : MigrationsAssembly
{
private readonly DbContext context;
public ContextAwareMigrationsAssembly(
ICurrentDbContext currentContext,
IDbContextOptions options,
IMigrationsIdGenerator idGenerator,
IDiagnosticsLogger<DbLoggerCategory.Migrations> logger) : base(currentContext, options, idGenerator, logger)
{
context = currentContext.Context;
}
/// <summary>
/// Modified from http://weblogs.thinktecture.com/pawel/2018/06/entity-framework-core-changing-db-migration-schema-at-runtime.html
/// </summary>
/// <param name="migrationClass"></param>
/// <param name="activeProvider"></param>
/// <returns></returns>
public override Migration CreateMigration(TypeInfo migrationClass, string activeProvider)
{
var hasCtorWithDbContext = migrationClass
.GetConstructor(new[] { typeof(DbContext) }) != null;
if (hasCtorWithDbContext)
{
var instance = (Migration)Activator.CreateInstance(migrationClass.AsType(), context);
instance.ActiveProvider = activeProvider;
return instance;
}
return base.CreateMigration(migrationClass, activeProvider);
}
}
Sostituisci il servizio IMigrationAssembly in DbContext con la tua classe personalizzata
protected override void OnConfiguring(DbContextOptionsBuilder optionsBuilder)
{
optionsBuilder.ReplaceService<IMigrationsAssembly, ContextAwareMigrationsAssembly>();
}
Quindi è possibile aggiungere un parametro DbContext
nella migrazione.
public Migration20180801(DbContext context)
{
DatabaseName = context.Database.GetDbConnection().Database;
}
Nel tuo caso, è possibile sostituire tutte le DbContext
riferimenti con IConfiguration
e l'istanza rilevante nella CreateMigration
override.