You need to enable JavaScript to run this app.
优惠活动
大模型
产品
解决方案
定价
更多

清洁架构下如何在Infrastructure层创建EF Core迁移?

清洁架构下EF Core迁移的实现方案

核心思路

清洁架构要求Web层(外层)不直接依赖数据访问相关包,所有数据访问逻辑集中在Infrastructure层(最外层的基础设施实现)。要解决迁移问题,关键是让EF Core工具能在不污染Web层的前提下,在Infrastructure层创建UsersDbContext实例——使用EF Core的IDesignTimeDbContextFactory接口是标准且合规的方案。

具体步骤

1. 在Infrastructure层添加必要的NuGet包

Infrastructure层作为数据访问实现层,完全可以引用EF Core相关工具包,这符合清洁架构的依赖规则:

dotnet add src/BFF/BFF.Infrastructure/BFF.Infrastructure.csproj package Microsoft.EntityFrameworkCore.Design

2. 实现设计时DbContext工厂

在Infrastructure层新建一个类,实现IDesignTimeDbContextFactory<UsersDbContext>,用于在迁移时手动创建UsersDbContext实例(绕过依赖注入,直接加载配置并初始化上下文):

using Microsoft.EntityFrameworkCore;
using Microsoft.EntityFrameworkCore.Design;
using Microsoft.Extensions.Configuration;
using System.IO;

namespace BFF.Infrastructure.Data
{
    public class UsersDbContextDesignTimeFactory : IDesignTimeDbContextFactory<UsersDbContext>
    {
        public UsersDbContext CreateDbContext(string[] args)
        {
            // 加载Web项目的配置文件(保持配置集中管理,也可以用Infrastructure自己的配置)
            var configBuilder = new ConfigurationBuilder()
                .SetBasePath(Path.Combine(Directory.GetCurrentDirectory(), "../BFF.Web"))
                .AddJsonFile("appsettings.json")
                .AddJsonFile("appsettings.Development.json", optional: true);

            var configuration = configBuilder.Build();
            var connectionString = configuration.GetConnectionString("UsersConnection");

            var options = new DbContextOptionsBuilder<UsersDbContext>()
                .UseSqlServer(connectionString) // 根据你的数据库类型调整(如UseNpgsql、UseSqlite)
                .Options;

            return new UsersDbContext(options);
        }
    }
}

注意:确保UsersDbContext有接收DbContextOptions<UsersDbContext>参数的构造函数(这是EF Core的标准构造方式)。

3. 执行迁移命令

使用以下命令创建迁移,指定Infrastructure为目标项目,Web为启动项目(Web层无需引用任何EF Core工具包):

dotnet ef migrations add UsersMig --context UsersDbContext --project src/BFF/BFF.Infrastructure/BFF.Infrastructure.csproj --startup-project src/BFF/BFF.Web/BFF.Web.csproj

为什么之前的命令会报错?

  • 直接以Web为启动项目执行迁移:EF工具需要Microsoft.EntityFrameworkCore.Design包来生成迁移,但你不想让Web层依赖此包,因此报错。
  • 以Infrastructure为启动项目执行迁移:类库项目没有宿主环境,EF工具无法通过依赖注入解析UsersDbContext的构造参数(如IConfiguration),导致无法创建实例。

而设计时工厂的作用就是告诉EF工具:不用依赖注入,直接用这个工厂方法创建DbContext,完美规避了上述两个问题,同时严格遵守清洁架构的依赖规则。

内容的提问来源于stack exchange,提问作者Szyszka947

相关产品推荐
方舟 Agent Plan

超全模态模型 × Harness 升级,最新支持 Deepseek-V4.1-Flash、GLM-5.3 系列、Doubao-Seedream-5.0-pro、Kimi-K3 (部分), 限时 9.9 元起

最近更新时间:2026.07.12 09:27:42