2013-03-29 4 views
15

Offenbar codiert IMigrationMetadata.Target den Zustand des EF-Modells. Kann ich damit das Modell für eine bestimmte Migration rekonstruieren?Kann ich ein EntityFramework-Modell von einer bestimmten Migration dekodieren?

+0

+1, wollen wir sie Migrationen automatisch und stattdessen ausgeführt werden, wenn ein Admin ruft sie vermeiden, laufen, so müssen wir in der Lage sein, ein Modell zu rekonstruieren, aus welcher die aktuelle Migration ist. –

+1

Könntest du ein wenig weiterarbeiten? Wie wo und wann möchten Sie das Modell rekonstruieren? Welches Problem möchten Sie lösen? –

Antwort

24

Ja, es ist möglich. Ich war selbst neugierig, was genau diese magischen Ressourcen-Strings speicherten. Durch digging into the Entity Framework source (siehe DbMigrator.GetLastModel()-Methode) fand ich heraus, dass die IMigrationMetadata.Target speichert nur eine Base-64-Zeichenfolge mit XML-Daten gezippt. Um dies zu testen, habe ich eine neue Konsolenanwendung ein einfaches Code-erstes Modell enthält wie folgt definiert:

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; } 
} 

Dann habe ich eine Migration des NuGet Package Manager Console:

PM> Enable-Migrations 
PM> Add-Migration MyMigration 

Next I hinzugefügt der folgende Code den Wert meiner Main() Methode der Anwendung in dieser Zeichenfolge zu entschlüsseln und sie an die Konsole Dump:

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()); 

Diese outputs an EDMX file stellt das Entitätsdatenmodell dar, das mit meiner DbContext verknüpft ist, die die Migration erstellt hat. Wenn ich diese Ausgabe in eine Datei mit der Erweiterung .edmx schreibe, kann ich sie mit Visual Studio öffnen und im Entity Designer anzeigen.

Dann, wenn ich aus irgendeinem Grund die DbContext und Entitätsklassen regenerieren wollte, die das Modell erzeugt, müsste ich nur folgendes:

  1. Fügen Sie die .edmx-Datei in ein Visual Studio-Projekt.
  2. Installieren Sie die EF 5.x DbContext Generator for C#, wenn ich es noch nicht habe.
  3. Fügen Sie die zugehörigen T4-Vorlagen hinzu, indem Sie im Kontextmenü des Projektknotens Add -> New Item auswählen.
  4. Ändern Sie die neu hinzugefügten .tt Dateien, ersetzen $edmxInputFile$ durch den Namen meiner .edmx Datei.
  5. Beobachten Sie, wie die beiden Vorlagen meine Code-First-Typen magisch zu ihren jeweiligen .cs Dateien regenerieren.

Hoffe, dass Ihre Frage beantwortet! :-D

+1

Kühl. Jetzt muss ich nur an eine tatsächliche Anwendung denken: D –

+0

Wie so viele Programmierung "Probleme", die ich "lösen".";-) – luksan

+1

Tolles Zeug @luksan, danke! Für alle Interessierten habe ich einen kleinen Gist erstellt, der das EDMX aus dem Ziel-Hash extrahieren und wieder komprimieren kann: https://gist.github.com/gligoran/87fe3e8eadf5db97ad03 Ich benutze dies, wenn ich eine Migration ändern muss, ohne den Rest der Kette zu stören.Ich extrahiere das EDMX von meiner Änderungsmigration, bearbeite das XML und komprimiere es zurück, um das neue Ziel zu erhalten, was ich dann für jede Migration tun muss das folgt dem geänderten. – gligoran

5

ich eine kleine Konsolenanwendung erstellt EDMX aus der Spalte Modell der __MigrationHistory Tabelle exportiert https://github.com/andreydil/EfMigrationModelDecoder
Sie /migration Parameter mit spezifischer Migration können wählen, das heißt:

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