如何描述自动迁移的细节

How to describe details of an automatic migration

Entity Framework Code-First 中,您可以根据模型中的代码更改启用自动迁移。

通过调用 Update-Database,这些变化是:

  1. 注册于[timestamp]_AutomaticMigration
  2. 生成 SQL 脚本并迁移数据库
  3. 将迁移存储在 table __MigrationHistory

__MigrationHistory table 中,模型列中将迁移描述为一个大的十六进制值。例如:

0x1F8B0800000000000400CD57CD6EDB3810BE2FB0EF20F0B40512313F976D20B5C8CAC9C2D83A09AAB4775A1ADBC492944A5281FD6C3DF491FA0A1D...

在 Visual Studio 的包管理器控制台中,您可以使用 Get-Migrations 检索自动迁移列表。

但是,似乎没有办法检索特定自动迁移的详细信息——无论是 SQL 脚本,还是受影响的模型和字段。

有没有一种我不知道的方法可以检索特定自动迁移的详细信息?

这个问题来自对自动迁移和显式迁移的误解。

我认为显式迁移需要您编写所有 up/down 更改。

Add-Migration 迁移更改会被自动迁移 自动放置到显式迁移文件 中。

显式迁移后调用 Update-Database 将迁移更改,但现在有一个详细说明更改的代码文件。

是的,有。

table __MigrationHistory 中的这个值是一个 GZiped Xml,包含 EDMX 架构。

我编写了以下代码来检索 EDMX 模型(此代码使用 C# 6

You can access this code on my gist also, with this link: https://gist.github.com/AlbertoMonteiro/45198dc80641ce1896e6

In this gist there is a C# 5 version, that you can paste in a console application.

#r "C:\Program Files (x86)\Reference Assemblies\Microsoft\Framework\.NETFramework\v4.5\System.Data.dll"
#r "C:\Program Files (x86)\Reference Assemblies\Microsoft\Framework\.NETFramework\v4.5\System.Xml.Linq.dll"
using System.Xml.Linq;
using System.IO.Compression;

public void DecompressDatabaseMigration(string migrationName, string databaseName)
{
    var connectionString = $@"Data source=.\sqlexpress;Initial catalog={databaseName};Integrated security=true";
    var sqlToExecute = String.Format("select model from __MigrationHistory where migrationId like '%{0}'", migrationName);

    using (var connection = new SqlConnection(connectionString))
    {
        connection.Open();

        var command = new SqlCommand(sqlToExecute, connection);

        var reader = command.ExecuteReader();
        if (!reader.HasRows)
        {
            throw new Exception("Now Rows to display. Probably migration name is incorrect");
        }

        while (reader.Read())
        {
            var model = (byte[])reader["model"];
            var decompressed = Decompress(model);
            File.WriteAllText(@"C:\temp\edmx.xml", decompressed.ToString());
        }
    }
}

public XDocument Decompress(byte[] bytes)
{
    using (var memoryStream = new MemoryStream(bytes))
    {
        using (var gzipStream = new GZipStream(memoryStream, CompressionMode.Decompress))
        {
            return XDocument.Load(gzipStream);
        }
    }
}

DecompressDatabaseMigration(Args[1], Args[0]);  

如您所见,Visual Studio 更新 1 中的新 C# REPL 中允许使用一些语法。

所以我用 .csx 扩展名保存这个文件然后我执行,在我的例子中 DecompileMigration.csx

csi DecompileMigration.csx

然后脚本将文件 emdx.xml 放入我的 C:\temp 文件夹,然后我会看到模型在这个特定的迁移中。

要使用VS 2015 update 1的REPL,可以

加载名为 VS2015 开发人员命令提示符的自定义 CMD

按Windows然后搜索此名称VS2015 的开发人员命令提示符

选项 1

C:\ProgramData\Microsoft\Windows\Start Menu\Programs\Visual Studio 2015\Visual Studio Tools

中打开

选项 2

打开 cmd 会话,然后执行以下命令

call "%vs140comntools%vsdevcmd.bat"

选项 3

在菜单Visual Studio2015 U1中打开VIEW > Other Windows > C# Interactive

如果您使用此选项,脚本中的 Args 成员将不起作用,因此您必须将 Args[0] 替换为您的数据库名称,并将 Args[0] 替换为您的数据库名称.