2013-03-29 36 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

相關問題