Reputation: 1416
How can we pass arguments to dotnet ef database update
?
I want to be able to update different databases with the use of arguments.
I've tried:
dotnet ef database update "Accept"
dotnet ef database update Accept
but it didn't work..
Or how I can put a switch to get different connectionString
from my configuration?
public ProjectContext CreateDbContext(string[] args)
{
IConfigurationRoot configuration = new ConfigurationBuilder()
.SetBasePath(Directory.GetCurrentDirectory())
.AddJsonFile("appsettings.json")
.Build();
// Find a way to get different connection string
var connectionString = configuration.GetConnectionString(args[0]);
var builder = new DbContextOptionsBuilder<ProjectContext>();
builder.UseSqlServer(connectionString);
return new ProjectContext(builder.Options);
}
Upvotes: 21
Views: 8491
Reputation: 329
Hope this answer will help people who are trying to resolve this using .net cli.
Custom arguments can be passed to IDesignTimeDbContextFactory<T>
using --
token as mentioned earlier, but I found missing actual example showing that basically there is no rule how you define them, e.g. can be -- -DbUser Admin
, -- DbUser=Admin
. Just make sure there is a space separator following --
. The rest is forwarded to design time context factory automatically.
With all this in mind the sample usage may look like:
dotnet ef database update -c YourDbContext -- -DbUser Admin -Password Secret
dotnet ef database update -c YourDbContext -- DbUser=Admin Password=Secret
Latter seems makes more sense as parameters arrive in single dimension array, so have to map param name with param value manually if you choose the first example. Also second one looks more clear to me as extra dashes make it more confusing.
More information here: learn.microsoft.com
Upvotes: 1
Reputation: 3775
from everything I ready here I basically ended up with CreateDbContext(string[] args)
the args
will get populated with anything after you initial CMD
The -- token directs dotnet ef to treat everything that follows as an argument and not try to parse them as options. Any extra arguments not used by dotnet ef are forwarded to the app. more here
will result with args
being populated with 4 args
this works as the --
passes the all else back to dotnet to set the args
As an example, when adding IDesignTimeDbContextFactory<YourContext>
interface to your Context adds the following method and this is where I am able to pass in the vars
public DataBaseContext CreateDbContext(string[] args)
{
Debugger.Launch();
Console.WriteLine($@"Args:");
foreach (var arg in args)
{
Console.WriteLine($"Arg: {arg}");
}
}
this will write out the 4 vars passed in -test something -testagain again
I post this answer to help expand on other answers here and see the full context
Upvotes: 1
Reputation: 70176
You can also set variables like this:
$env:SqlConnectionString="Server=tcp:mySqlServerStuffxxx"
Add-Migration InitialCreate
Update-Database
Source:
It won't work for ConnectionStrings.DefaultConnection
though. It will give the following error:
The property 'DefaultConnection' cannot be found on this object. Verify that the property exists and can be set.
Upvotes: 0
Reputation: 6258
.NET 5 releases in a couple weeks from the time of this answer. So this is possible to change.
Answer Now
The .NET 5, and the associated EF Core 5+ NuGets support this. In Package Manager you can type:
Add-Migration YourMigrationName -Args "Space Separated Args"
Update-Database -Args "Space Separated Args"
For example, I use this:
Update-Database -Args MyConnName
In my Startup project I have a config file (Or appsettings.json) that has that connection string key, and I pull that in.
Note I said .NET Core 5. This will be have a full release in a few weeks from now. So in a few weeks this answer may be simple. But until then, you may need to install Preview versions (And NuGet PreReleases)
Answer Prior to now
There were lacking options when this question was asked, though there were options, like using dotnet ef commands
with AppArgs
, as discussed here. But these have changed, and are also now accessible from PM Console as discussed in the above "Now" answer.
Upvotes: 8
Reputation: 16705
I had a similar issue recently trying to get an Asp.Net Core app to read the connection string. It turns out that you don't need the IDesignTimeDbContextFactory
. Instead, just make sure that your context has a paramerless constructor, and use something like this in the startup:
services.AddDbContext<ApplicationDbContext>(options =>
options.UseSqlServer(
Configuration.GetConnectionString("DefaultConnection")));
This should resolve to whichever connection string you have configured. If you did want to use two separate connections at the same time (which I realise you didn't want), you could do this by registering multiple DbContexts at this point; for example:
services.AddDbContext<ApplicationDbContext>(options =>
options.UseSqlServer(
Configuration.GetConnectionString("DefaultConnection")));
services.AddDbContext<MyDbContext>(options =>
options.UseSqlServer(
Configuration.GetConnectionString("OtherConnection")));
Upvotes: 0