【问题标题】:Can I get decode an EntityFramework Model from a specified migration?我可以从指定的迁移中解码 EntityFramework 模型吗?
【发布时间】:2013-03-29 19:06:40
【问题描述】:

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

【问题讨论】:

  • +1,我们希望避免自动运行迁移,而是在管理员调用它们时运行它们,因此我们需要能够从当前迁移中重建模型。
  • 您能详细说明一下吗?比如您想在何时何地重建模型?你想解决什么问题?

标签: entity-framework entity-framework-5


【解决方案1】:

是的,这是可能的。我自己很好奇那些魔法资源字符串到底存储了什么。通过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 包管理器控制台创建了一个迁移:

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 -&gt; New Item 添加相关的 T4 模板。
  4. 修改新添加的.tt文件,将$edmxInputFile$替换为我的.edmx文件名。
  5. 观看这两个模板神奇地将我的代码优先类型重新生成为它们各自的 .cs 文件。

希望能回答您的问题! :-D

【讨论】:

  • 酷。现在我只需要考虑一个实际的应用程序:D
  • 好东西@luksan,谢谢!对于任何感兴趣的人,我创建了一个小 Gist,可以从目标哈希中提取 EDMX 并将其再次压缩:gist.github.com/gligoran/87fe3e8eadf5db97ad03。当我需要更改迁移而不干扰链的其余部分时,我会使用它。我从更改迁移中提取 EDMX,编辑 XML 并将其压缩回来以获取新目标。然后,我必须为更改后的每个迁移执行此操作。
【解决方案2】:

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

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

【讨论】:

    【解决方案3】:

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

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

    【讨论】:

      【解决方案4】:

      你也可以使用 SQL...

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

      【讨论】:

      • 我在我的 MSSQL 2008 中尝试过,它不起作用。警告“解压缩”不存在。你用的是哪个版本的sqlserver?
      • SQL Server 2016 及更高版本。抱歉...我很久没见过 SQL 2008 服务器了。
      猜你喜欢
      • 1970-01-01
      • 2020-08-17
      • 1970-01-01
      • 1970-01-01
      • 2016-12-24
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      • 2012-12-20
      相关资源
      最近更新 更多