RavenMigrations 6.0.2

dotnet add package RavenMigrations --version 6.0.2                
NuGet\Install-Package RavenMigrations -Version 6.0.2                
此命令旨在在 Visual Studio 的包管理器控制台中使用,因为它使用了 NuGet 模块的 Install-Package 版本。
<PackageReference Include="RavenMigrations" Version="6.0.2" />                
对于支持 PackageReference 的项目,请将此 XML 节点复制到项目文件中以引用该包。
paket add RavenMigrations --version 6.0.2                
#r "nuget: RavenMigrations, 6.0.2"                
#r 指令可用于 F# Interactive 和 Polyglot Notebooks。将此复制到交互式工具或脚本的源代码中以引用该包。
// Install RavenMigrations as a Cake Addin
#addin nuget:?package=RavenMigrations&version=6.0.2

// Install RavenMigrations as a Cake Tool
#tool nuget:?package=RavenMigrations&version=6.0.2                

Raven Migrations

Join the chat at https://gitter.im/migrating-ravens/RavenMigrations

Build status

快速入门

    PM > Install-Package RavenMigrations

简介

Raven Migrations 是一个用于 RavenDB 的迁移框架,以帮助您在长时间内对您的数据库执行一些常见任务。该框架 API 在很大程度上受到 Fluent Migrator 的影响。

哲学

我们相信对您的领域所做的任何更改都应在您的代码中可见,并相应地反映。在“飞行中”更改事物可能会导致问题,而迁移可以在将其公开到生产环境之前进行测试和彻底审查。

一旦迁移进入您的生产环境,就 永远不要 在您的代码中更改它。将迁移视为更改的历史记录。

概念

每个迁移都有几个您需要了解的元素。此外,还有一些有助于您构建项目以利用此库的泛型概念。

迁移

迁移如下所示

// #1 - specify the migration number
[Migration(1)]                 
public class PeopleHaveFullNames : Migration // #2 inherit from Migration
{
    // #3 Do the migration using RQL.
    public override void Up()
    {
        this.PatchCollection(@"
            from People as person
            update {
                person.FullName = person.FirstName + ' ' + person.LastName;
            }
        ");
    }
    // #4 optional: undo the migration
    public override void Down()
    {
        this.PatchCollection(@"
            from People as person
            update {
                delete person.FullName;
            }
        ");
    }
}

要运行迁移,在 ASP.NET Core 应用程序中的样子如下。

// In Startup.cs
public void ConfigureServices(IServiceCollection services)
{
    // Add the MigrationRunner into the dependency injection container.
    services.AddRavenDbMigrations();
}

public void Configure(IApplicationBuilder app, ...)
{
    // Run pending Raven migrations.
    var migrationService = app.ApplicationServices.GetRequiredService<MigrationRunner>();
    migrationService.Run();
}

没有使用 ASP.NET Core?您可以手动创建运行器

// Skip dependency injection and run the migrations.

// Create migration options, using all Migration objects found in the current assembly.
var options = new MigrationOptions();
options.Assemblies.Add(Assembly.GetExecutingAssembly());

// Create a new migration runner. docStore is your RavenDB IDocumentStore. Logger is an ILogger<MigrationRunner>.
var migrationRunner = new MigrationRunner(docStore, options, logger);
migrationRunner.Run();

每个迁移的重要部分都编了号

  1. 每次迁移都必须使用 MigrationAttribute 修饰,并需要用 长整型 值进行初始化。对于小型团队,简单的整数即可(例如,第一个补丁有 Migration(1),第二个补丁有 Migration(2),依此类推)。如果您与大型团队协作,补丁编号可能会冲突,我们建议您使用 yyyyMMddHHmmss 格式的 DateTime 标记,例如 20131031083545。这有助于各个团队在下一个迁移编号上避免猜测和冲突。
  2. 每次迁移都必须实现 Migration 基类。这为您提供了对基本功能和实现 UpDown 的访问权限。它还为您提供对 Raven DocumentStoreILogger 实例的访问权限。
  3. Up 是迁移执行时发生的方法。正如上面的示例所示,我们正在添加一个文档。
  4. Down 是迁移回滚时发生的方法。这可能并不总是可能的,但如果可以的话,它很可能就是 Up 的反转。

在每次迁移中,您都有访问文档存储的权限,这样您就可以对自己存储引擎的任何操作。此文档存储与您的应用程序使用的相同。

运行器

Raven Migrations 随附一个迁移运行器。它会扫描所有提供的程序集,查找实现 Migration 基类的任何类,并按照它们的迁移值对它们进行排序。

每次迁移执行后,都会将一个类型为 MigrationDocument 的文档插入到您的数据库中,以确保下次运行器执行时不会再次执行该迁移。当迁移回滚时,文档会被删除。

您可以通过传递一个操作到 .AddRavenDbMigrations 调用来修改运行器选项。

services.AddRavenDbMigrations(options =>
{
   // Configure the migration options here
});
防止同时迁移

默认情况下,Raven Migrations 通过设置 Raven compare/exchange 值来防止同时运行迁移。例如:如果您有 2 个应用程序实例正在运行,并且这两个实例都试图运行迁移。当 Raven Migrations 检测到这种情况时,它会阻止其他实例运行迁移并记录一条警告信息。

Raven Migrations 通过使用 Raven compare/exchange 值 来实现这一点,以确保同时运行的迁移不超过一个。在迁移运行期间,它会在您的数据库中设置一个 raven-migrations-lock compare/exchange 值;其值设置为超时期限。

请注意,如果您意外终止迁移(例如,如果您的网络宿主在迁移过程中终止或杀死您的应用程序),迁移将不会运行,直到您删除 raven-migrations-lock compare/exchange 值,或者直到其超时期限过期。默认超时为 1 小时。

如果您希望允许同时运行多个迁移或更改迁移超时锁,您可以使用覆写功能来实现。

services.AddRavenDbMigrations(options =>
{
    // Allow simultaneous migrations - beware, here be dragons. Defautls to true.
    options.PreventSimultaneousMigrations = false;

    // Change how long the migrations lock can be held for. Defautls to 1 hour.
   options.SimultaneousMigrationTimeout = TimeSpan.FromMinutes(5);
});

// In Startup.cs
public void ConfigureServices(IServiceCollection services)
{
    // pass the option single instance, the rest stays as is.
    services.AddRavenDbMigrations(singleInstance: true);
}

... 

配置文件

我们理解,有时您希望在特定环境中运行特定的迁移,因此 Raven Migrations 支持配置文件。例如,一些迁移可能仅在开发中运行,通过在迁移上装饰 "development" 配置文件并设置包含配置文件的选项来执行该迁移。

[Migration(3, "development")]
public class Development_Migration : Migration
{
    public override void Up()
    {
        using (var session = Db.OpenSession())
        {
            session.Store(new { Id = "development-1" });
            session.SaveChanges();
        }
    }
}

...
// Add the MigrationRunner and configure it to run development migrations only.
services.AddRavenDbMigrations(options => options.Profiles = new[] { "development" } });

您还可以通过在属性中设置多个配置文件名称,来指定特定的配置文件属于多个配置文件。

[Migration(3, "development", "demo")]

此迁移会在 (或都) 开发和演示配置文件在 MigrationOptions 中指定时运行。

高级迁移

在每个迁移实例内部,您应使用 RavenDB 的

迁移.PatchCollection

` Migration.PatchCollection ` 是一个辅助方法,它通过 RQL

public override void Up()
{
   this.PatchCollection("from People update { p.Foo = 'Hello world!' }");
}
使用依赖注入服务进行数据库迁移
[Migration(1)]
public class MyMigrationUsingServices : Migration
{
	private IFoo foo;

	// Inject an IFoo for use in our patch.
	public MyMigrationUsingServices(IFoo foo)
	{
		this.foo = foo;
	}

	public override void Up()
	{
		// Do something with foo
	}
}
示例:添加和删除属性

假设你开始使用单个“Name”属性

public class Person
{
    public string Id { get; set; }
    public string Name { get; set; }
}

但你想要改为使用两个属性,分别为“FirstName”和“LastName”

public class Person
{
    public string Id { get; set; }
    public string FirstName { get; set; }
    public string LastName { get; set; }
}

你现在需要迁移你的文档,否则在加载你的新Person时,你将丢失数据。以下迁移使用RQL来分离出名字和姓氏

[Migration(1)]
public class PersonNameMigration : Migration
{
    public override void Up()
    {
        this.PatchCollection(@"
            from People as p
            update {
                var names = p.Name.split(' ');
                p.FirstName = names[0];
                p.LastName = names[1];
                delete p.Name;
            }
        ");
    }

    // Undo the patch
    public override void Down()
    {
        this.PatchCollection("this.Name = this.FirstName + ' ' + this.LastName;");
    }
}

集成

我们建议你在应用程序启动时运行迁移,以确保任何你已做的更改在应用程序启动前应用到你的应用程序。如果你不想在这里执行,你可以选择在独立的应用程序外进行。如果你使用ASP.NET Core,你可以在Startup.cs中运行它们。

public void ConfigureServices(IServiceCollection services)
{
    // Add the MigrationRunner singleton into the dependency injection container.
    services.AddRavenDbMigrations();

    // ...

    // Get the migration runner and execute pending migrations.
    var migrationRunner = services.BuildServiceProvider().GetRequiredService<MigrationRunner>();
    migrationRunner.Run();
}

没有使用 ASP.NET Core?您可以手动创建运行器

// Skip dependency injection and run the migrations.

// Create migration options, using all Migration objects found in the current assembly.
var options = new MigrationOptions();
options.Assemblies.Add(Assembly.GetExecutingAssembly());

// Create a new migration runner. docStore is your RavenDB IDocumentStore. Logger is an ILogger<MigrationRunner>.
var migrationRunner = new MigrationRunner(docStore, options, logger);
migrationRunner.Run();

解决方案结构

我们建议你创建一个名为“Migrations”的文件夹,然后根据迁移编号和名称命名文件。

\Migrations
    - 001_FirstMigration.cs
    - 002_SecondMigration.cs
    - 003_ThirdMigration.cs

这种方法的优势在于,你的IDE会按字母顺序排列迁移,让你能够轻松地找到第一个和最后一个迁移。

贡献

欢迎任何大小的贡献!请阅读我们的行为准则贡献指南,然后加入我们!

感谢

感谢Sean Kearon,他帮助构建了这个迁移框架并对其做出了贡献。还要感谢Darrel Portzline和Khalid Abuhakmeh在项目早期版本的贡献。

版本控制

本项目力求遵循semver指南。有关更多信息,请参阅贡献维护指南。

产品 兼容和额外的计算目标框架版本。
.NET net8.0 兼容。 net8.0-android 已计算。 net8.0-browser 已计算。 net8.0-ios 已计算。 net8.0-maccatalyst 已计算。 net8.0-macos 已计算。 net8.0-tvos 已计算。 net8.0-windows 已计算。
兼容目标框架
包含的目标框架(在包中)
了解有关目标框架.NET Standard的更多信息。

NuGet 包

此包未被任何NuGet包使用。

GitHub 仓库 (1)

显示沉积在RavenMigrations上的1个最受欢迎的GitHub仓库

仓库 星标
ravendb/samples-yabt
"Another Bug Tracker" 解决方案示例,适用于RavenDB和.NET,并带有Angular UI。
版本 下载 最后更新时间
6.0.2 409 8/2/2024
6.0.1 12,836 1/13/2024
6.0.0 96 1/13/2024
5.0.2 18,029 1/9/2024
5.0.1 217,325 3/21/2022
5.0.0 49,525 7/26/2020
4.3.0 7,970 5/4/2020
4.1.7 27,735 1/21/2019
4.1.6 716 1/18/2019
4.1.4 727 1/4/2019
4.1.3 692 1/3/2019
4.1.2 770 11/27/2018
4.1.1 1,085 10/23/2018
4.1.0 777 10/9/2018
4.0.0 832 9/17/2018
3.0.0 912 7/19/2018
2.1.0 34,581 6/20/2016
2.0.0 2,531 1/22/2016
1.2.0 8,961 5/20/2015
1.1.0 1,051 5/18/2015
1.0.1 1,872 7/10/2014
1.0.0 2,876 10/28/2013

更新至.NET 8,Raven 6。修复了可空性相关问题。