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

无需CLI:为Entity Framework Core配置自定义迁移文件夹

自定义EF Core迁移文件输出路径的实现方案

EF Core迁移命令依赖设计时注入的IMigrationsScaffolder服务,要实现自动按年月分文件夹管理迁移文件,需通过装饰器模式包装默认服务,并通过设计时服务配置注册自定义实现,而非直接修改运行时服务。

1. 安装依赖包

确保项目已安装Microsoft.EntityFrameworkCore.Design包:

dotnet add package Microsoft.EntityFrameworkCore.Design

2. 实现自定义迁移脚手架装饰器

创建类包装默认的MigrationsScaffolder,动态生成按年月划分的输出路径:

using Microsoft.EntityFrameworkCore.Design;
using Microsoft.EntityFrameworkCore.Migrations.Design;
using Microsoft.EntityFrameworkCore.Migrations.Operations;
using System;
using System.Collections.Generic;
using System.IO;
using System.Threading.Tasks;

public class DateTimePartitionedMigrationsScaffolder : IMigrationsScaffolder
{
    private readonly IMigrationsScaffolder _innerScaffolder;
    private readonly ILogger<DateTimePartitionedMigrationsScaffolder> _logger;

    public DateTimePartitionedMigrationsScaffolder(IMigrationsScaffolder innerScaffolder, ILogger<DateTimePartitionedMigrationsScaffolder> logger)
    {
        _innerScaffolder = innerScaffolder;
        _logger = logger;
    }

    public async Task<ScaffoldedMigration> ScaffoldMigrationAsync(string migrationName, string rootNamespace, string subNamespace = null, string language = null)
    {
        var now = DateTime.Now;
        // 生成年月格式的子路径和命名空间
        var targetSubNamespace = $"Data.Migrations.{now.Year}.{now.Month:D2}";
        var targetDir = $"Data/Migrations/{now.Year}/{now.Month:D2}";

        _logger.LogInformation($"迁移文件将输出至: {targetDir}");

        // 调用默认脚手架逻辑,传入自定义命名空间
        var scaffoldedMigration = await _innerScaffolder.ScaffoldMigrationAsync(
            migrationName,
            rootNamespace,
            targetSubNamespace,
            language);

        // 修正文件输出路径,确保文件生成到目标文件夹
        scaffoldedMigration.MigrationFile.Path = Path.Combine(targetDir, Path.GetFileName(scaffoldedMigration.MigrationFile.Path));
        scaffoldedMigration.MetadataFile.Path = Path.Combine(targetDir, Path.GetFileName(scaffoldedMigration.MetadataFile.Path));

        return scaffoldedMigration;
    }

    // 其余接口方法直接委托给默认实现
    public Task DeleteMigrationAsync(string projectDir, string rootNamespace, bool force, string language = null)
        => _innerScaffolder.DeleteMigrationAsync(projectDir, rootNamespace, force, language);

    public Task<IReadOnlyList<string>> GetMigrationNamesAsync(string projectDir, string rootNamespace, string language = null)
        => _innerScaffolder.GetMigrationNamesAsync(projectDir, rootNamespace, language);

    public Task<string> GetMigrationIdAsync(string migrationName, string projectDir, string rootNamespace, string language = null)
        => _innerScaffolder.GetMigrationIdAsync(migrationName, projectDir, rootNamespace, language);
}

3. 注册设计时服务

创建实现IDesignTimeServices的类,替换默认的迁移脚手架服务:

using Microsoft.EntityFrameworkCore.Design;
using Microsoft.EntityFrameworkCore.Migrations.Design;
using Microsoft.Extensions.DependencyInjection;

public class CustomDesignTimeServices : IDesignTimeServices
{
    public void ConfigureDesignTimeServices(IServiceCollection services)
    {
        services.AddScoped<IMigrationsScaffolder>(sp =>
        {
            var innerScaffolder = sp.GetRequiredService<MigrationsScaffolder>();
            var logger = sp.GetRequiredService<ILogger<DateTimePartitionedMigrationsScaffolder>>();
            return new DateTimePartitionedMigrationsScaffolder(innerScaffolder, logger);
        });
    }
}

4. 验证效果

执行迁移命令:

# PowerShell命令
Add-Migration TestMigration

# 或DotNet CLI命令
dotnet ef migrations add TestMigration

控制台会输出路径日志,迁移文件将自动生成到Data/Migrations/YYYY/MM/目录下,命名空间同步调整为项目根命名空间.Data.Migrations.YYYY.MM。

注意事项

  • CustomDesignTimeServices需与DbContext处于同一项目,确保EF Core设计时工具能扫描到
  • 移除迁移时(Remove-Migration或dotnet ef migrations remove),默认服务会自动根据迁移ID定位到对应文件夹的文件,无需额外修改
  • .NET 6+顶级语句Program.cs无需额外配置,设计时服务会被自动加载

内容的提问来源于stack exchange,提问作者Steffen Cole Blake

相关产品推荐
方舟 Agent Plan

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

最近更新时间:2026.07.08 22:03:37