如何按年/版本对迁移进行分组?

huangapple go评论73阅读模式
英文:

How to group migrations by year/version?

问题

我意识到随着时间的推移,迁移文件夹中会有越来越多的迁移。因此,我想按年份、应用程序版本和功能来对这些迁移进行分组。例如,可能会有以下文件夹:
migrations/v23.02/
migrations/v23.01/
migrations/v22.04/
这个版本/年份/功能名称将存储在app.config中。

我知道迁移文件夹可以更改,但我想知道如何在不更改此值的情况下执行整个数据库设置。因此,当我第一次在db-server上运行'update-database',并且在我的配置中将值设置为'v23.01'时,实际上我想运行来自'v22.04'、'v23.01'、'v23.2'文件夹的迁移。

我知道有DbMigrationsConfiguration,但我不确定如何设置它来处理一个上下文的多个文件夹。

英文:

I realized that with time there is more and more migrations in migration folder. So I want to group those migration by year, application version, feature. For example there could be folders:
migrations/v23.02/
migrations/v23.01/
migrations/v22.04/
And this version/year/feature name would be stored inside app.confi.

I know that migration folder can be changed, but I want to know how to do it with way when I will be able to setup whole database without changing this value form first to latest one. So when I will run 'update-database' for the first time on db-server and in my configuration will be value 'v23.01', in fact I want to run migrations from 'v22.04', 'v23.01', 'v23.2' folders.

I how there is DbMigrationsConfiguration but I'm not sure hot to setup it to handle multiple folders for one context.

答案1

得分: 1

创建自定义 IDbMigrationsConfiguration 实现:

public class CustomDbMigrationsConfiguration<TContext> : DbMigrationsConfiguration<TContext>
    where TContext : DbContext
{
    public string MigrationVersion { get; set; }

    public CustomDbMigrationsConfiguration()
    {
        // 如果需要,可以在此处设置其他配置
        AutomaticMigrationsEnabled = false;
        // 其他配置设置...
    }

    protected override IEnumerable<string> GetMigrations()
    {
        // 从基本实现中获取基本迁移
        var migrations = base.GetMigrations().ToList();

        // 根据 MigrationVersion 从版本/年/特性文件夹加载迁移
        if (!string.IsNullOrEmpty(MigrationVersion))
        {
            var assembly = Assembly.GetExecutingAssembly(); // 将此更改为您的迁移程序集

            var versionYearFeatureFolder = Path.Combine("migrations", MigrationVersion);

            if (assembly.GetManifestResourceNames().Any(r => r.Contains(versionYearFeatureFolder)))
            {
                var resourceNames = assembly.GetManifestResourceNames()
                    .Where(r => r.Contains(versionYearFeatureFolder))
                    .OrderBy(r => r);

                migrations.AddRange(resourceNames);
            }
        }

        return migrations;
    }
}

在应用程序配置中存储 MigrationVersion 值:
在 appsettings.json(或者根据项目类型可能是 web.config)中,添加一个 MigrationVersion 属性:

{
  "ConnectionStrings": {
    "Default": "YourConnectionStringHere"
  },
  "MigrationVersion": "v23.02"
}

在 DbContext 类中初始化 CustomDbMigrationsConfiguration:

public class YourDbContext : DbContext
{
    public YourDbContext() : base("Default")
    {
        var migrationVersion = ConfigurationManager.AppSettings["MigrationVersion"];
        Database.SetInitializer(new MigrateDatabaseToLatestVersion<YourDbContext, CustomDbMigrationsConfiguration<YourDbContext>>()
        {
            MigrationVersion = migrationVersion
        });
    }
}

使用此设置,当您运行 update-database 或执行数据库初始化时,将根据配置中 MigrationVersion 的值加载并应用来自指定版本/年/特性文件夹的迁移。这允许您以更有结构的方式组织您的迁移,并仅应用与特定版本相关的迁移。

英文:

Create a custom IDbMigrationsConfiguration implementation:

public class CustomDbMigrationsConfiguration&lt;TContext&gt; : DbMigrationsConfiguration&lt;TContext&gt;
    where TContext : DbContext
{
    public string MigrationVersion { get; set; }

    public CustomDbMigrationsConfiguration()
    {
        // Set any other configurations here if needed
        AutomaticMigrationsEnabled = false;
        // Other configuration settings...
    }

    protected override IEnumerable&lt;string&gt; GetMigrations()
    {
        // Get the base migrations from the base implementation
        var migrations = base.GetMigrations().ToList();

        // Load migrations from the version/year/feature folder based on the MigrationVersion
        if (!string.IsNullOrEmpty(MigrationVersion))
        {
            var assembly = Assembly.GetExecutingAssembly(); // Change this to your migrations assembly

            var versionYearFeatureFolder = Path.Combine(&quot;migrations&quot;, MigrationVersion);

            if (assembly.GetManifestResourceNames().Any(r =&gt; r.Contains(versionYearFeatureFolder)))
            {
                var resourceNames = assembly.GetManifestResourceNames()
                    .Where(r =&gt; r.Contains(versionYearFeatureFolder))
                    .OrderBy(r =&gt; r);

                migrations.AddRange(resourceNames);
            }
        }

        return migrations;
    }
}

In your application configuration, store the MigrationVersion value:
In the appsettings.json (or web.config depending on your project type), add a property for MigrationVersion:

{
  &quot;ConnectionStrings&quot;: {
    &quot;Default&quot;: &quot;YourConnectionStringHere&quot;
  },
  &quot;MigrationVersion&quot;: &quot;v23.02&quot;
}

Initialize the CustomDbMigrationsConfiguration in the DbContext class:

public class YourDbContext : DbContext
{
    public YourDbContext() : base(&quot;Default&quot;)
    {
        var migrationVersion = ConfigurationManager.AppSettings[&quot;MigrationVersion&quot;];
        Database.SetInitializer(new MigrateDatabaseToLatestVersion&lt;YourDbContext, CustomDbMigrationsConfiguration&lt;YourDbContext&gt;&gt;()
        {
            MigrationVersion = migrationVersion
        });
    }
}

With this setup, when you run update-database or perform database initialization, the migrations from the specified version/year/feature folder will be loaded and applied based on the value of MigrationVersion in your configuration. This allows you to organize your migrations in a more structured manner and apply only the migrations related to a specific version.

huangapple
  • 本文由 发表于 2023年7月31日 18:42:09
  • 转载请务必保留本文链接:https://go.coder-hub.com/76802844.html
匿名

发表评论

匿名网友

:?: :razz: :sad: :evil: :!: :smile: :oops: :grin: :eek: :shock: :???: :cool: :lol: :mad: :twisted: :roll: :wink: :idea: :arrow: :neutral: :cry: :mrgreen:

确定