2013-03-29 8 views
15

Apparentemente IMigrationMetadata.Target codifica lo stato del modello EF. Posso usare questo per ricostruire il modello per una particolare migrazione?È possibile ottenere la decodifica di un modello EntityFramework da una migrazione specificata?

+0

+1, vogliamo evitare l'esecuzione automatica e invece le migrazioni eseguirli quando un amministratore li invoca, quindi abbiamo bisogno di essere in grado di ricostruire un modello da qualunque migrazione corrente è. –

+1

Potresti elaborare un po '? Ti piace dove e quando vorresti ricostruire la modella? Quale problema vorresti risolvere? –

risposta

24

Sì, è possibile. Ero curioso di sapere esattamente cosa stessero conservando quelle stringhe di risorse magiche. Con digging into the Entity Framework source (vedere il metodo DbMigrator.GetLastModel()), ho scoperto che lo IMigrationMetadata.Target memorizza solo una stringa base 64 contenente dati XML compressi. Per verificare ciò, ho creato una nuova applicazione console contenente un semplice modello di codice-prima definito come segue:

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

Poi ho creato una migrazione utilizzando il pacchetto console NuGet Responsabile:

PM> Enable-Migrations 
PM> Add-Migration MyMigration 

successivo ho aggiunto il seguente codice per il metodo di mia applicazione Main() per decodificare il valore in quella stringa e discarica alla console:

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

Questo outputs an EDMX file che rappresenta il modello di dati entità associato al mio DbContext che ha creato la migrazione. Se scrivo questo output su un file con l'estensione .edmx, sono in grado di aprirlo con Visual Studio e visualizzarlo in Entity Designer.

Poi, se per qualche motivo ho voluto rigenerare le DbContext e entità classi che hanno prodotto il modello, avrei bisogno di fare solo le seguenti:

  1. aggiungere il file .edmx a un progetto di Visual Studio.
  2. Installare lo EF 5.x DbContext Generator for C# se non lo si possiede già.
  3. Aggiungere i modelli T4 correlati selezionando Add -> New Item dal menu di scelta rapida del nodo progetto.
  4. Modificare i file .tt appena aggiunti, sostituendo $edmxInputFile$ con il nome del file .edmx.
  5. Guarda come i due modelli rigenerano magicamente i miei tipi code-first ai rispettivi file .cs.

Spero che risponda alla tua domanda! :-D

+1

Freddo. Ora ho solo bisogno di pensare a un'applicazione vera e propria per questo: D –

+0

Come tanti "problemi" di programmazione che "risolvo".";-) – luksan

+1

Grandi cose @luksan, grazie! Per chiunque fosse interessato ho creato un piccolo Gist che può estrarre l'EDMX dall'hash di destinazione e comprimerlo di nuovo: https://gist.github.com/gligoran/87fe3e8eadf5db97ad03 Lo uso quando ho bisogno di cambiare una migrazione senza disturbare il resto della catena: estrao EDMX dalla mia migrazione di modifica, modifica l'XML e lo comprimo per ottenere il nuovo target, quindi devo farlo per ogni migrazione quello segue quello cambiato. – gligoran

5

ho creato una piccola applicazione console di esportare EDMX dalla colonna modello della tabella __MigrationHistory https://github.com/andreydil/EfMigrationModelDecoder
Si può scegliere di migrazione specifica utilizzando /migration parametro, vale a dire:

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