2013-03-29 31 views
15

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

+0

+1,我们要避免自动,而是运行的迁移运行它们时,管理员调用它们,所以我们需要能够重建模型无论从任何当前的迁移。 –

+1

能否详细说明一下?像你想在何时何地重建模型?你想解决什么问题? –

回答

24

是的,这是可能的。我很好奇这些神奇的资源字符串正在存储什么。通过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打开它并在Entity Designer中查看它。

然后,如果由于某种原因,我想重新产生该模型DbContext和实体类,我只需要做到以下几点:

  1. .edmx文件添加到Visual Studio项目。
  2. 如果我还没有安装EF 5.x DbContext Generator for C#
  3. 通过从项目节点上下文菜单中选择Add -> New Item来添加相关的T4模板。
  4. 修改新添加的.tt文件,用我的.edmx文件的名称替换$edmxInputFile$
  5. 观看这两个模板神奇地将我的代码优先类型重新生成到它们各自的.cs文件。

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

+1

很酷。现在我只需要考虑一个实际的应用程序:D –

+0

像我这样解决的很多编程“问题”。“;-) – luksan

+1

伟大的东西@luksan,谢谢!对于任何感兴趣的人,我已经创建了一个小小的Gist,可以从目标散列中提取EDMX并再次压缩它:https://gist.github.com/gligoran/87fe3e8eadf5db97ad03 。当我需要改变迁移而不影响链的其他部分时,我使用它。我从我的更改迁移中提取EDMX,编辑XML并压缩它以获得新目标。然后,我必须为每个迁移执行此操作那跟着改变的那个。 – gligoran

相关问题