.NET Core 3.1, EF Core 5.0 preview 6.
I am using Simple Injector 5.0 to register IMyContextFactory
(I'm not using services.AddDbContext<>()
).
My MyContext
have all constructors set to private because I use ContextFactory without tenantId and sometimes with few different tenantIds at one request, so I make sure that everyone will use IMyContextFactory
injection instead of MyContext
and to prevent creating new MyContext()
in controllers etc.
But how to do Update-Database
?
Update-Database
I always have error Login failed for user ''.
, but I can run and connect to database from my WebAPI project without any problem (my ConnectionString is good).services.AddDbContext<MyContext>()
, make constructors for MyContext
as public and get this context from scope.ServiceProvider.GetRequiredService<MyContext>()
in Program.cs, because my IMyContextFactory
was not inside ServiceProvider
. (via https://learn.microsoft.com/pl-pl/ef/core/managing-schemas/migrations/applying?tabs=vs#apply-migrations-at-runtime)How to achieve that only with Simple Injector?
The solutions is to add ConnectionString to your IDesignTimeDbContextFactory
implementation:
// Fix for "Unable to create an object of type 'MyContext'. For the different patterns supported at design time, see https://go.microsoft.com/fwlink/?linkid=851728" error while creating migration
public class MyContextDesignFactory : IDesignTimeDbContextFactory<MyContext>
{
private string _appsettingsPath = "./../Path/To/ProjectWithAppsettingsJSON";
public MyContext CreateDbContext(string[] args)
{
// In 90% we don't have ASPNETCORE_ENVIRONMENT here, so set fallback to Development
var environment = Environment.GetEnvironmentVariable("ASPNETCORE_ENVIRONMENT") ?? "Development";
var config = new ConfigurationBuilder()
.SetBasePath(Path.Combine(Directory.GetCurrentDirectory(), _appsettingsPath))
.AddJsonFile("appsettings.json", optional: false, reloadOnChange: true)
.AddJsonFile($"appsettings.{environment}.json", optional: true)
.Build();
Console.WriteLine($"Default ConnectionString comes from appsettings file.{Environment.NewLine}You can override it by using `dotnet ef database update --connection MyConnectionString`");
// Use ConnectionString from appsettings inside WebAPI to fix `Update-Database` command from Package Manager Console
// We still can override ConnectionString by `dotnet ef database update --connection MyConnectionString`
var optionsBuilder = new DbContextOptionsBuilder<MyContext>()
.UseSqlServer(config["ConnectionString"]);
return MyContext.MyContextFactory.GetMyContext(optionsBuilder.Options);
}
}