我有类库
Core
、Application
、Infrastructure
,以及一个 Web
项目,该项目是 ASP NET 7 项目。
Infrastructure
层是数据访问层,所以我在这里定义了DbContext
并且也想在这里进行迁移。所以我使用了以下命令:
add-migration UsersMig -Context UsersDbContext -o Migrations/Users
但是这个命令喊道:
您的启动项目“Web”未引用 Microsoft.EntityFrameworkCore.Design。实体框架核心工具需要此包才能正常工作。确保您的启动项目正确,安装软件包,然后重试。
但我不想在我的
Web
层中引用与数据访问相关的内容。所以我将我的类库设置为启动项目(是的,非常糟糕的主意,classlib 不可执行...),如下所示:
dotnet ef migrations add UsersMig --context UsersDbContext --project src/BFF/BFF.Infrastructure/BFF.Infrastructure.csproj --startup-project src/BFF/BFF.Infrastructure/BFF.Infrastructure.csproj
我得到了错误:
无法创建“UsersDbContext”类型的对象。有关设计时支持的不同模式,请参阅 https://go.microsoft.com/fwlink/?linkid=851728
那么我需要做什么才能在我的
Infrastructure
层中进行迁移而不影响 Clean Architecture?
您希望使 Web 层与数据访问问题脱钩是正确的。您看到的错误是因为 EF Core 工具需要
Microsoft.EntityFrameworkCore.Design
包提供的某些设计时服务。但是,您不一定需要将此包添加到 Web 层。相反,您可以将其添加到定义 DbContext 的基础设施层。
尝试下面我的建议,在您的基础设施层中设置迁移,而不违反清洁架构原则:
添加必要的包: 确保您的基础设施项目具有以下 NuGet 包:
Microsoft.EntityFrameworkCore
Microsoft.EntityFrameworkCore.Design
Microsoft.EntityFrameworkCore.SqlServer
(或您正在使用的任何数据库提供商)DbContext 配置: 确保您的
UsersDbContext
具有接受 DbContextOptions<UsersDbContext>
作为参数的构造函数。这对于 EF Core 工具能够在设计时创建上下文实例是必要的。
public UsersDbContext(DbContextOptions<UsersDbContext> options) : base(options)
{
}
设计时 DbContext 工厂: 在基础设施层中创建设计时
IDesignTimeDbContextFactory<TContext>
实现。该工厂帮助 EF Core 工具实例化您的 DbContext。
using Microsoft.EntityFrameworkCore;
using Microsoft.EntityFrameworkCore.Design;
public class UsersDbContextFactory : IDesignTimeDbContextFactory<UsersDbContext>
{
public UsersDbContext CreateDbContext(string[] args)
{
var optionsBuilder = new DbContextOptionsBuilder<UsersDbContext>();
optionsBuilder.UseSqlServer("Your_Connection_String_Here");
return new UsersDbContext(optionsBuilder.Options);
}
}
注意:将
"Your_Connection_String_Here"
替换为您的实际连接字符串。这仅适用于设计时,因此可以在此处对其进行硬编码,但要确保您不会意外地将敏感数据提交到源代码管理。
运行迁移命令: 现在,您应该能够运行迁移命令,而无需指定
--startup-project
:
dotnet ef migrations add UsersMig --context UsersDbContext --project src/BFF/BFF.Infrastructure/BFF.Infrastructure.csproj
更新数据库: 当您准备好将迁移应用到数据库时,可以使用
database update
命令:
dotnet ef database update --context UsersDbContext --project src/BFF/BFF.Infrastructure/BFF.Infrastructure.csproj
通过执行这些步骤,您可以使 Web 层与数据访问问题脱钩,并仍然在基础设施层中利用 EF Core 迁移。