如何描述自动迁移的细节
How to describe details of an automatic migration
在 Entity Framework Code-First 中,您可以根据模型中的代码更改启用自动迁移。
通过调用 Update-Database
,这些变化是:
- 注册于
[timestamp]_AutomaticMigration
- 生成 SQL 脚本并迁移数据库
- 将迁移存储在 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]
替换为您的数据库名称.
在 Entity Framework Code-First 中,您可以根据模型中的代码更改启用自动迁移。
通过调用 Update-Database
,这些变化是:
- 注册于
[timestamp]_AutomaticMigration
- 生成 SQL 脚本并迁移数据库
- 将迁移存储在 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]
替换为您的数据库名称.