Logo Questions Linux Laravel Mysql Ubuntu Git Menu
 

Can I get decode an EntityFramework Model from a specified migration?

Apparently IMigrationMetadata.Target encodes the state of the EF model. Can I use this to reconstruct the model for a particular migration?

like image 958
Tim Lovell-Smith Avatar asked Mar 29 '13 19:03

Tim Lovell-Smith


People also ask

How does migration work in Entity Framework?

The migrations feature in EF Core provides a way to incrementally update the database schema to keep it in sync with the application's data model while preserving existing data in the database.

Which of the following migrations are there in Entity Framework?

Entity Framework introduced a migration tool that automatically updates the database schema when your model changes without losing any existing data or other database objects. It uses a new database initializer called MigrateDatabaseToLatestVersion. There are two kinds of Migration: Automated Migration.

What is Entity Framework Code First migrations?

Code First Migrations is the recommended way to evolve your application's database schema if you are using the Code First workflow. Migrations provide a set of tools that allow: Create an initial database that works with your EF model. Generating migrations to keep track of changes you make to your EF model.


2 Answers

Yes, it is possible. I was myself curious what exactly those magic resource strings were storing. By digging into the Entity Framework source (see the DbMigrator.GetLastModel() method), I found out that the IMigrationMetadata.Target just stores a base-64 string containing gzipped XML data. To test this, I created a new console application containing a simple code-first model defined as follows:

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

Then I created a migration using the NuGet Package Manager Console:

PM> Enable-Migrations
PM> Add-Migration MyMigration

Next I added the following code to my application's Main() method to decode the value in that string and dump it to the 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());

This outputs an EDMX file representing the Entity Data Model associated with my DbContext that created the migration. If I write this output to a file with the .edmx extension, I'm able to open it with Visual Studio and view it in the Entity Designer.

Then if for some reason I wanted to regenerate the DbContext and entity classes that produced the model, I would need only do the following:

  1. Add the .edmx file to a Visual Studio project.
  2. Install the EF 5.x DbContext Generator for C# if I don't already have it.
  3. Add the related T4 templates by selecting Add -> New Item from project node context menu.
  4. Modify the newly added .tt files, replacing $edmxInputFile$ with the name of my .edmx file.
  5. Watch as the two templates magically regenerate my code-first types to their respective .cs files.

Hope that answers your question! :-D

like image 51
luksan Avatar answered Sep 20 '22 13:09

luksan


I created a small console app to export EDMX from the Model column of the __MigrationHistory table https://github.com/andreydil/EfMigrationModelDecoder
You can choose specific migration using /migration parameter, i.e:

EfMigrationModelDecoder.Cli.exe "<connectionString here>" /migration:Init
like image 26
Andrey Avatar answered Sep 23 '22 13:09

Andrey