Ho due progetti.
1). Console Console NetCore
Ho un punto di accesso
class Program
{
private static IConfiguration Configuration { get; set; }
static void Main(string[] args)
{
IConfigurationRoot configurationRoot = new ConfigurationBuilder()
.AddJsonFile($"appsettings.json", true, true)
.Build();
Configuration = configurationRoot;
// create service collection
var serviceCollection = new ServiceCollection();
ConfigureServices(serviceCollection);
// create service provider
serviceCollection.BuildServiceProvider();
}
private static void ConfigureServices(ServiceCollection serviceCollection)
{
string connectionString = Configuration.GetConnectionString("DefaultConnection");
serviceCollection.AddDbContext<MyDbContext>(options => options.UseSqlServer(connectionString));
}
}
e un appsettings.json
{
"ConnectionStrings": {
"DefaultConnection": "****"
}
}
2) .NetStandard Lib (contiene DbContext)
Voglio essere in grado di creare uno script di migrazione usando le migrazioni di dotnet ef migrations add [NAME]
e ho capito se eseguo il comando mentre nella cartella lib posso scegliere un progetto di avvio per eseguire le migrazioni.
D:\Lib> dotnet ef migrations add InitialCreate -s ..\ConsoleApp\
Sono riuscito a farlo funzionare aggiungendo una classe nella stessa cartella di MyDbContext che implementa IDesignTimeDbContextFactory<MyDbContext>
Posso aggiungere una stringa di connessione e funziona perfettamente.
public class MyDbContextFactory : IDesignTimeDbContextFactory<MyDbContext>
{
public MyDbContext CreateDbContext(string[] args)
{
DbContextOptionsBuilder<MyDbContext> builder = new DbContextOptionsBuilder<MyDbContext>();
builder.UseSqlServer("****", optionsBuilder => optionsBuilder.MigrationsAssembly(typeof(MyDbContext).GetTypeInfo().Assembly.GetName().Name));
return new MyDbContext(builder.Options);
}
}
Il problema che ho è che voglio usare la stringa di connessione all'interno dell'app appsettings.json della console.
È possibile e come posso farlo?
Grazie in anticipo.
Ok penso di avere una soluzione, anche se non sono sicuro se sono contento.
Il mio program.cs è ora:
class Program
{
static void Main(string[] args)
{
}
}
Ho spostato la classe implementando IDesignTimeDbContextFactory<MyDbContext>
dal progetto con MyDbContext all'applicazione console e ora sembra:
public class MyDbContextFactory : IDesignTimeDbContextFactory<MyDbContext>
{
public MyDbContext CreateDbContext(string[] args)
{
IConfiguration configuration = new ConfigurationBuilder()
.AddJsonFile("appsettings.json", true, true)
.Build();
string connectionString = configuration.GetConnectionString("DefaultConnection");
DbContextOptionsBuilder<MyDbContext> builder = new DbContextOptionsBuilder<MyDbContext>();
builder.UseSqlServer(connectionString,
optionsBuilder => optionsBuilder.MigrationsAssembly(typeof(MyDbContext).GetTypeInfo().Assembly.GetName().Name));
return new MyDbContext(builder.Options);
}
}
quindi l'app della console è:
Il comando che sto utilizzando è ancora
D:\Lib> dotnet ef migrations add InitialCreate -s ..\ConsoleApp\
Non è stato possibile rimuovere il riferimento su Microsoft.EntityFrameworkCore.SqlServer poiché gli script di migrazione sono stati salvati nel progetto lib e avevano riferimenti alla libreria. Se avessi gli script di migrazione in una cartella diversa, significherebbe che potrei rimuovere la dipendenza, ma per ora sono d'accordo.