entity framework - que - ¿Puedo obtener decodificar un modelo EntityFramework a partir de una migración específica?
que es code first (3)
Creé una aplicación de consola pequeña para exportar EDMX desde la columna Modelo de la tabla __MigrationHistory https://github.com/andreydil/EfMigrationModelDecoder
Puede elegir la migración específica usando el parámetro /migration
, es decir:
EfMigrationModelDecoder.Cli.exe "<connectionString here>" /migration:Init
Al parecer, IMigrationMetadata.Target codifica el estado del modelo EF. ¿Puedo usar esto para reconstruir el modelo para una migración en particular?
Creé una secuencia de comandos de PowerShell para extraer la última migración de una base de datos a un archivo edmx.
https://gist.github.com/otto-gebb/93d021c8fd300646dba0073a77585a94
Sí, es posible. Yo mismo sentía curiosidad por saber exactamente qué estaban almacenando esas cadenas de recursos mágicos. Al profundizar en la fuente de Entity Framework (ver el método DbMigrator.GetLastModel()
), descubrí que IMigrationMetadata.Target
solo almacena una cadena base-64 que contiene datos XML comprimidos con gzip. Para probar esto, creé una nueva aplicación de consola que contiene un modelo simple de código primero definido de la siguiente manera:
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; }
}
Luego creé una migración usando la Consola de NuGet Package Manager:
PM> Enable-Migrations
PM> Add-Migration MyMigration
A continuación, agregué el siguiente código al método Main()
mi aplicación para decodificar el valor en esa cadena y volcarlo en la consola:
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());
Esto genera un archivo EDMX que representa el modelo de datos de entidad asociado con mi DbContext
que creó la migración. Si escribo esta salida en un archivo con la extensión .edmx
, puedo abrirlo con Visual Studio y verlo en el Diseñador de entidades.
Luego, si por alguna razón quisiera regenerar las clases de DbContext
y de entidad que produjeron el modelo, solo necesitaría hacer lo siguiente:
- Agregue el archivo
.edmx
a un proyecto de Visual Studio. - Instale EF 5.x DbContext Generator for C # si aún no lo tengo.
- Agregue las plantillas T4 relacionadas seleccionando
Add -> New Item
del menú contextual del nodo del proyecto. - Modifique los archivos
.tt
recién agregados, reemplazando$edmxInputFile$
con el nombre de mi archivo.edmx
. - Observe cómo las dos plantillas regeneran mágicamente los tipos de código primero a sus respectivos archivos
.cs
.
Espero que responda a su pregunta! :-RE