无法将 Entity Framework Core 迁移添加到 .NET Standard 2.0 项目
我有一个包含许多项目的解决方案.其中之一 (Domain
) 是一个 .NET Standard 2.0 项目,我在其中制作了我的 EF Core DbContext
实现,我想为其启用数据库迁移.
I've got a Solution with many projects.
One of them (Domain
) is a .NET Standard 2.0 project where I made my EF Core DbContext
implementation for which I want to enable database migrations.
我看到各种博客和问答论坛都解释了问题,但由于 .NET Core 较新版本或(可能)适用于我的特定解决方案配置,因此所有建议的解决方案似乎都不适合我.
I saw various blogs and Q/A forums where the problem was explained but none of the proposed solutions seem to work for me because of the .NET Core newer version or (probably) for my particular solution configuration.
解决方案项目
- 引擎(.NET Core 2.1 控制台应用程序)
- Web API(.NET Core 2.1 库)
- 应用程序(.NET Core 2.1 库)
- 域(.NET Standard 2.0 库)
- WindowsService(.NET Core 2.1 控制台应用程序)
WindowsService
是启动项目,其中创建并封装了 Engine
的实例,以作为 Windows 服务或控制台应用程序运行(用于调试).
The WindowsService
is the Startup project, where an instance of the Engine
is created and encapsulated to run as Windows Service or Console application (for debug).
Engine
是真正的核心应用程序,其中 Kestrel
自托管 Web 服务器的实例被配置为 Web API 并实例化.其他组件也会被实例化并保持活动状态(UDP 侦听器、机器看门狗等...).
The Engine
is the real core application, where an instance of Kestrel
self-host Web server is configured as Web API and instantieted. Also other components are instantiated and stay alive (UDP listener, machine watchdog, etc...).
WebAPI
有 Startup
类但没有 Program
类,因为所有配置和 Web 服务器启动都在 Engine 内完成.Program.cs
类.
WebAPI
has Startup
class but no Program
class, since all the configuration and the Web server start is done inside Engine.Program.cs
class.
依赖
- WindowsService => 引擎
- 引擎 => WebAPI
- WebAPI => 应用程序、域
- 应用 => 域
第一次尝试是简单地从 PMC 启动 add-migration Initial
并将 Domain
项目作为目标,但它变成了:
The first attempt was to simply launch add-migration Initial
from PMC with Domain
project as target, but it turns to:
无法创建类型为MyDbContext"的对象.添加一个'IDesignTimeDbContextFactory' 到项目,或查看 https://go.microsoft.com/fwlink/?linkid=851728 对于设计时支持的其他模式.
Unable to create an object of type 'MyDbContext'. Add an implementation of 'IDesignTimeDbContextFactory' to the project, or see https://go.microsoft.com/fwlink/?linkid=851728 for additional patterns supported at design time.
然后我遵循了 这个问题,但是:
Then I followed the proposed solution on this question, but:
add-migration Initial
来自 PMC,在将 MyWebAPI
(没有Program
类)设置为启动项目后,转向:
add-migration Initial
from PMC, after setting MyWebAPI
(with noProgram
class) as startup project, turns to:
找不到任何兼容的框架版本指定的框架Microsoft.NETCore.App",版本2.1.0"不是找到了.
It was not possible to find any compatible framework version The specified framework 'Microsoft.NETCore.App', version '2.1.0' was not found.
- 检查应用程序依赖项并定位安装在以下位置的框架版本:C:Program Filesdotnet
- 安装 .NET Core 先决条件可能有助于解决此问题:http://go.microsoft.com/fwlink/?LinkID=798306&clcid=0x409
- 可以从以下位置安装 .NET Core 框架和 SDK:https://aka.ms/dotnet-download
- 安装了以下版本:2.0.5 在 [C:Program FilesdotnetsharedMicrosoft.NETCore.App]2.0.6 在 [C:Program FilesdotnetsharedMicrosoft.NETCore.App]2.0.7 在 [C:Program FilesdotnetsharedMicrosoft.NETCore.App]2.0.9 在 [C:Program FilesdotnetsharedMicrosoft.NETCore.App]2.1.2 在 [C:Program FilesdotnetsharedMicrosoft.NETCore.App]
add-migration Initial
来自 PMC,在向域库项目文件中添加了一个额外的目标框架 (netcoreapp2.1
) 后,我得到了同样的结果第一次尝试时出错.
add-migration Initial
from PMC, after adding an additional target framework (netcoreapp2.1
) to the Domain library project file, leads me to the same error as the 1st attempt.
add-migration Initial
来自 PMC,在添加对 Microsoft.EntityFrameworkCore.SqlServer.Design v1.1.6
的引用后总是导致与第一个相同的错误尝试.
add-migration Initial
from PMC, after adding a reference to Microsoft.EntityFrameworkCore.SqlServer.Design v1.1.6
always leads to same error as the 1st attempt.
我该怎么办?
更新
这是删除不必要的库引用后的新 Domain.csproj
文件.
This is the new Domain.csproj
file after removing the unecessary libraries references.
<ItemGroup>
<PackageReference Include="Microsoft.EntityFrameworkCore" Version="2.1.1" />
<PackageReference Include="Microsoft.EntityFrameworkCore.SqlServer" Version="2.1.1" />
<PackageReference Include="Microsoft.EntityFrameworkCore.Tools" Version="2.1.1" />
<PackageReference Include="Newtonsoft.Json" Version="11.0.2" />
</ItemGroup>
所有项目中的所有库都是最新的.
All libraries in all projects are up to date.
- 从 Runtime 和
SDK
>here - 我猜你现在需要.NET Core 2.1.302
-
Microsoft.EntityFrameworkCore.SqlServer.Design
不再需要,因为它包含在 SDK 中.也不需要EntityFrameworkCore
的csproj
字段中的CLI
引用. - 确保
Manage NuGet 包
窗口显示所有更新. 在您的 Web 项目实现中添加
IDesignTimeDbContextFactory
接口 - 它将被自动找到并用于 EFAdd-Migration
(或dotnet ef
...analogs) 命令在Package Manager Console
- Download and install appropriate
Runtime
andSDK
from here - I guess you need.NET Core 2.1.302
at the moment -
Microsoft.EntityFrameworkCore.SqlServer.Design
is not needed anymore as it's included to SDK.CLI
reference incsproj
fiels forEntityFrameworkCore
is not needed as well. - Make sure you
Manage NuGet packages
window shows all updated. Add anywhere in you web project implementation of
IDesignTimeDbContextFactory
interface - it will be found automatically and used for EFAdd-Migration
(ordotnet ef
... analogues) command inPackage Manager Console
public class DesignTimeActivitiesDbContextFactory : IDesignTimeDbContextFactory<ActivitiesDbContext>
{
public ActivitiesDbContext CreateDbContext(string[] args)
{
DbContextOptionsBuilder<ActivitiesDbContext> builder = new DbContextOptionsBuilder<ActivitiesDbContext>();
var context = new ActivitiesDbContext(
builder
.UseSqlServer("Data Source=(local)LocalDB;Initial Catalog=DB_name;Integrated Security=True;")
.Options);
return context;
}
}
要从您的 appsettings
配置文件中读取连接字符串,您可以执行以下操作:
To read the connection string from your appsettings
config file you could do the following:
public class DesignTimeActivitiesDbContextFactory : IDesignTimeDbContextFactory<ActivitiesDbContext>
{
public ActivitiesDbContext CreateDbContext(string[] args)
{
var builder = new ConfigurationBuilder()
.SetBasePath(Path.Combine(Directory.GetCurrentDirectory()))
.AddJsonFile("appsettings.Development.json", optional: false);
var config = builder.Build();
var optionsBuilder = new DbContextOptionsBuilder<ActivitiesDbContext>()
.UseSqlServer(config.GetConnectionString("DefaultConnection"));
return new ActivitiesDbContext(optionsBuilder.Options);
}
}
注意:在上面的代码工厂中,将使用appsettings.Development.json
文件中定义的连接字符串值.并且连接名称是DefaultConnection
.换句话说,此设计时间工厂用于 Code First
命令,例如 Add-Migration
、Update-Database
等...)并将它们应用到为 Development
环境配置的数据库连接.
NOTE: in the above code factory will use connection string value defined in appsettings.Development.json
file. And connection name is DefaultConnection
. In other words, this disign time factory is used for the Code First
commands like Add-Migration
, Update-Database
, etc...) and will apply them to the database connection configured for Development
environment.