I'm playing with EF Core 2.0 and have 3 env in my app: dev, staging and prod. Now I want to apply db schema to specific database. However I faced with a problem. When I executing dotnet ef database drop (update)
for example, it's trying to get production env by default.
How could I specify what environment should be used? My DbContextFactory looks like that:
public class MyDbContextFactory : IDbContextFactory<MyDbContext>
{
public MyDbContext Create(string[] args) => //how to pass something to this args?
WebHost.CreateDefaultBuilder(args)
.UseStartup<Startup>()
.Build().Services.GetRequiredService<MyDbContext>();
}
it was something like:
dotnet ef database drop -e development
in version 1.1
, but this was removed from version 2.0
.
set ASPNETCORE_ENVIRONMENT=development
dotnet ef database drop
also seems not working.
Using multiple context types One way to create multiple migration sets is to use one DbContext type per provider. Specify the context type when adding new migrations. You don't need to specify the output directory for subsequent migrations since they are created as siblings to the last one.
Step 1 − Before running the application you need to enable migration. Step 2 − Open Package Manager Console from Tools → NuGet Package Manger → Package Manger Console. Step 3 − Migration is already enabled, now add migration in your application by executing the following command.
After creating a migration file using the add-migration command, you have to update the database. Execute the Update-Database command to create or modify a database schema. Use the –verbose option to view the SQL statements being applied to the target database.
Multiple DbContext was first introduced in Entity Framework 6.0. Multiple context classes may belong to a single database or two different databases.
What I gathered from here is that the -e MyCustomEnvironment
is not available in the EF Core Design Tools for Core 2.x
To set Environment Variables I discovered you have the following choices depending on your usecase
set ASPNETCORE_ENVIRONMENT <Environment Name>
setx ASPNETCORE_ENVIRONMENT <Environment Name>
"Start" -> "Edit the system environment Variables" -> "Environment Variables" -> "New"
export ASPNETCORE_ENVIRONMENT=<Environment Name>
cd ~
echo 'export ASPNETCORE_ENVIRONMENT=<Environment Name>' >> .bashrc
This will actually export the Variable everytime .bashrc is executed. I'm not sure if this is the way to go on Linux but it worked for me.
Also in my case I didn't want the StartUp code to run since I feel like for a DesignTime action its not neccessary to register all the Services etc of my Application. This could be done like so:
var basePath = AppDomain.CurrentDomain.BaseDirectory;
var envName = Environment.GetEnvironmentVariable("ASPNETCORE_ENVIRONMENT");
var builder = new ConfigurationBuilder()
.SetBasePath(basePath)
.AddJsonFile("appsettings.json")
.AddJsonFile($"appsettings.{envName}.json", true)
.AddEnvironmentVariables();
var config = builder.Build();
var customOptions = config.GetSection("database").Get<DatabaseOptions>();
Also if you have more complex szenarios you now might want to create some small batch or shell skripts
Well, to be honest I don't know exact answer for that question. I think environment variables should work, but the way how you set them are pretty much depend from environment you working for. So it will be one story on linux, different for on Windows (again different for PowerShell) and something elso on MacOS.
this works for me on Linux
and in bash console on Windows
:
ASPNETCORE_ENVIRONMENT="{NAME_OF_ENV}";dotnet ef {somecommand you want to execute}
In Powershell
you could try something like that:
$env:ASPNETCORE_ENVIRONMENT="{NAME_OF_ENV}"
dotnet ef {somecommand you want to execute}
However, even it's migration, it's still a console app inside. So you could just ask user to enter environment from console with something like:
Console.WriteLine("Enter environment you want to use");
var env = Console.ReadLine();
WebHost.CreateDefaultBuilder(args)
.UseEnvironment(env)
.UseStartup<Startup>()
.Build().Services.GetRequiredService<MyDbContext>();
This is of course not a perfect solution, but if you out of options - this could be a workaround. You could pass other param that way as well.
If you love us? You can donate to us via Paypal or buy me a coffee so we can maintain and grow! Thank you!
Donate Us With