Command line connection string for EF core database update
Keep both connection strings in appsettings.json
. Inherit a child context class from the main one and override OnConfiguring
with another connection string:
public class ScaffoldContext : MyDbContextName
{
protected override void OnConfiguring(DbContextOptionsBuilder optionsBuilder)
{
string scaffoldConnStr = ConfigurationManager.ConnectionStrings["scaffoldConnStr"].ConnectionString;
optionsBuilder.UseSqlServer(scaffoldConnStr);
}
}
Then use:
dotnet ef database update -c ScaffoldContext
I liked the idea of a scaffolding DbContext, but I found some issues (somehow solvable, I guess) and also some consideration on where to keep connection strings. Those led me to another, more crude solution, so I thought I'd share all that here.
This is about the general approach, and consequent solution:
- I don't like to store staging/production connection strings under source control. So I would pass that through an environment variable set in a temporary command window (or maybe on the fly on command-line, although I was not able to make that work). At that point, if I'm setting an environment variable, I might as well override initial connection string used by
MyDbContextName
, instead of adding a new one. Thus the whole scaffolding DB context thing could be overcome doing this way.
Other issues I found along the way:
Initial DbContext had dependencies injected into constructor, so child context had to to the same. This made
dotnet ef
commands complain about missing parameterless constructor.To overcome that, child context as well was registered at startup with
.AddDbContext<ChildDbContext>(...)
. This also required for ChildDbContext to be injected both with aDbContextOptions<ParentDbContext>
as well as aDbContextOptions<ChildDbContext>
. After that,dotnet-ef
still found issues with instantiating ChildDbContext, as that needed also a dependency onIConfiguration
which could not be found. Maybe (?) this is due to the fact thatdotnet-ef
does not run through the whole application startup.
As I said, I guess the issues could be solved after all, but still I'm questioning the real value of a scaffolding context in case you don't want to save connection strings in dedicated appsettings files. One counter argument could be that you might forget the environment variable set to the remote connection string, but then you just have to close the command window as soon as you complete migration. HTH
In EF Core 5.0, you will pass the connection string in the command line like this,
dotnet ef database update --connection "connection string"
Reference: https://docs.microsoft.com/en-us/ef/core/what-is-new/ef-core-5.0/whatsnew#new-command-line-parameters-for-namespaces-and-connection-strings
In a Linux terminal:
export ASPNETCORE_ENVIRONMENT="Development"
dotnet ef database update
Where ASPNETCORE_ENVIRONMENT match with appsettings.Development.json and the properly connectionstring configured.