I have two projects.
1) .NetCore Console App
I have a an entry point
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));
}
}
and an appsettings.json
{
"ConnectionStrings": {
"DefaultConnection": "****"
}
}
2) .NetStandard Lib (contains DbContext)
I want to be able to create a migration script using dotnet ef migrations add [NAME]
and i've worked out if I run the command whilst in the lib folder I can target a startup project to run the migrations.
D:\Lib> dotnet ef migrations add InitialCreate -s ..\ConsoleApp\
I managed to get this working by adding a class in the same folder as MyDbContext that implements IDesignTimeDbContextFactory<MyDbContext>
I can add a connection string and it runs perfectly.
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);
}
}
The problem I have is I want to use the connection string from within the console app's appsettings.json.
Is it possible and how can I do it?
Thanks in advance.
Ok I think I have a solution, though i'm not sure if i'm happy with it.
My program.cs is now:
class Program
{
static void Main(string[] args)
{
}
}
I moved the class implementing IDesignTimeDbContextFactory<MyDbContext>
from the project with MyDbContext to the console application and it now looks like:
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);
}
}
so the console app is:
The command i'm running is still
D:\Lib> dotnet ef migrations add InitialCreate -s ..\ConsoleApp\
I couldn't remove the reference on Microsoft.EntityFrameworkCore.SqlServer as the migration scripts were saved to the lib project and had references to the library. If I had the migration scripts going to a different folder that would mean I could remove the dependency, but i'm ok with that for now.