I am building an application in ASP.NET Core 2.0 and I am having problems with EntityFramework Migrations.
I have my DbContext in a separate project (SolutionName\ProjectNamePrefix.Data) and therefore I created an implementation for the IDesignTimeDbContextFactory interface.
I wanted to use different connection strings for different environments and I need appsettings.json
for that.
So after a quick search I found that I can create a new IConfigurationRoot
object inside the CreateDbContext
function as shown here:
https://codingblast.com/entityframework-core-idesigntimedbcontextfactory/
I added that and then for testing, tried to run dotnet ef migrations list -c MyContext
from the Data project root folder.
Then I got the following error:
The configuration file 'appsettings.json' was not found and is not optional. The physical path is 'C:\dev\*SolutionName*\*ProjectNamePrefix*.Data\bin\Debug\netcoreapp2.0\appsettings.json'.
So, basically, I tried 3 options for getting the correct root path:
Directory.GetCurrentDirectory();
env.ContentRootPath;
(IHostingEnvironment
object, I found a way to get it here: https://github.com/aspnet/Home/issues/2194)AppDomain.CurrentDomain.BaseDirectory;
and all of them returned the same ..\bin\debug\netcoreapp2.0\
path. When I run the Data project from VS, then the two first options give me the correct project root folder.
Is there a way to get the correct project content root folder?
Because when I added --verbose to the EF command, it logged out a row:
Using content root 'C:\dev\FitsMeIdentity\FitsMeIdentity.Data\'.
So I understand that EF somehow knows the project root but all the options mentioned above return the path for the already built application.
The only option I found that works is that I change Copy output to root folder
to Copy always
but found from here: https://www.benday.com/2017/02/17/ef-core-migrations-without-hard-coding-a-connection-string-using-idbcontextfactory/ that it's not a good idea.
At first I even thought about creating a Constructor for the IDesignTimeDbContextFactory implementation which gets IOptions as a parameter but that didn't work, had the same problem as explained here: Injecting Env Conn String into .NET Core 2.0 w/EF Core DbContext in different class lib than Startup prj & implementing IDesignTimeDbContextFactory
No. You can't do this, and more to the point: you're not supposed to do this. The whole entire point of IDesignTimeDbContextFactory
is that it's a way to get a DbContext
instance from in a context where there is no ASP.NET Core framework to work with, i.e. from a class library. If you're running migrations from an ASP.NET Core project, you don't need it, and if you're not, none of the configuration stuff is available.
Additionally, it's only to be used for development, hence the "DesignTime" part of the name. As a result, there's no need for stuff like switching between connection strings for different environments. Just hard-code the connection string as the docs detail.