我可以从特定的迁移中解码实体框架模型吗?

时间:2013-03-29 19:06:41

标签: entity-framework entity-framework-5

显然,IMigrationMetadata.Target对EF模型的状态进行编码。 我可以使用它来重建特定迁移的模型吗?

4 个答案:

答案 0 :(得分:27)

是的,有可能。我很好奇这些神奇的资源字符串究竟存储了什么。通过digging into the Entity Framework source(请参阅DbMigrator.GetLastModel()方法),我发现IMigrationMetadata.Target只存储包含gzip压缩XML数据的base-64字符串。为了测试这个,我创建了一个新的控制台应用程序,其中包含一个简单的代码优先模型,定义如下:

public class ContactContext : DbContext
{
    public virtual IDbSet<Contact> Contacts { get; set; }
}

public class Contact 
{
    public int Id {get; set;}
    public string FirstName { get; set; }
    public string LastName { get; set; }
}

然后我使用NuGet Package Manager控制台创建了一个迁移:

PM> Enable-Migrations
PM> Add-Migration MyMigration

接下来,我将以下代码添加到我的应用程序的Main()方法中,以解码该字符串中的值并将其转储到控制台:

var migration = new MyMigration();
var metadata = (IMigrationMetadata)migration;
var compressedBytes = Convert.FromBase64String(metadata.Target);
var memoryStream = new MemoryStream(compressedBytes);
var gzip = new GZipStream(memoryStream, CompressionMode.Decompress);
var reader = new StreamReader(gzip);
Console.WriteLine(reader.ReadToEnd());

outputs an EDMX file 表示与创建迁移的DbContext关联的实体数据模型。如果我将此输出写入具有.edmx扩展名的文件,我可以使用Visual Studio打开它并在实体设计器中查看它。

然后,如果由于某种原因我想重新生成生成模型的DbContext和实体类,我只需要执行以下操作:

  1. .edmx文件添加到Visual Studio项目中。
  2. 如果我还没有,请安装EF 5.x DbContext Generator for C#
  3. 从项目节点上下文菜单中选择Add -> New Item,添加相关的T4模板。
  4. 修改新添加的.tt文件,将$edmxInputFile$替换为.edmx文件的名称。
  5. 观看两个模板,将我的代码优先类型重新生成各自的.cs文件。
  6. 希望能回答你的问题! :-D

答案 1 :(得分:5)

我创建了一个小型控制台应用程序,用于从__MigrationHistory表https://github.com/andreydil/EfMigrationModelDecoder的Model列导出EDMX
您可以使用/migration参数选择特定的迁移,即:

EfMigrationModelDecoder.Cli.exe "<connectionString here>" /migration:Init

答案 2 :(得分:2)

我创建了一个PowerShell脚本来提取从数据库到edmx文件的最新迁移。

https://gist.github.com/otto-gebb/93d021c8fd300646dba0073a77585a94

答案 3 :(得分:0)

您还可以使用SQL ...

SELECT CONVERT(xml, DECOMPRESS(Model)) FROM [dbo].[__MigrationHistory] WHERE MigrationId = 'NameOfMigration'
相关问题