Click here to Skip to main content
65,938 articles
CodeProject is changing. Read more.
Articles / Languages / C#

IDbContextFactory which gets Connection String at runtime and triggers Automatic Migrations

0.00/5 (No votes)
4 Feb 2013CPOL 28.9K  
Sample code showing how to implement IDbContextFactory for retrieving ConnectionString at runtime and trigger automatic migrations. For use with DI and IoC or if you have different databases with the same model.

Introduction

This sample code is for using Entity Framework 5 when you want to specify the Context you use (Connection, Initializer, and Configuration) at Runtime.

Background 

It took me two weeks of gathering Information how to run Automatic Migration from code without Package Manager Console and how to do this when I want to specify the Connection String at runtime. Further I don't want to use any .config files or others static configurations.

Using the code

I use different ContextFactories for testing, development and production. In combination with Ninject an UnitOfWork pattern I'm able use the right context for the right purpose. Here a sample code of my Factory for Unit Testing. 

The DbContext (WPH_BusinessContext in this case) itself just contains the DbSets and the OnModelCreating handler to specify the mappings done in the FluentAPI. 

Note: the Migration will throw a Exception if there is data loss. There is also a sample how to set DbInitializers, but it's commented out.  

C#
public class TestDBContextFactory : IDbContextFactory<WPH_BusinessContext>
{
  public WPH_BusinessContext Create()
  {
     //set connection string at runtime here
     string connectionString = Properties.Settings.Default.TestDB;
     var connectionInfo = new DbConnectionInfo(connectionString, "System.Data.SqlClient");

     bool doInitialize = false;
     //Set initializer here
     //Database.SetInitializer<WPH_BusinessContext>(new DropCreateDatabaseAlways<WPH_BusinessContext>());
     //doInitialize = true;       

     var contextInfo = new DbContextInfo(typeof(WPH_BusinessContext), connectionInfo);
     var context = contextInfo.CreateInstance();
     context.Configuration.LazyLoadingEnabled = true;
     context.Configuration.ProxyCreationEnabled = true;

     if (doInitialize)
     {
        context.Database.Initialize(false);
     }

     bool doMigration = false;
     try
     {
        doMigration = !context.Database.CompatibleWithModel(true);
     }
     catch (NotSupportedException)
     {
        //if there are no metadata for migration
        doMigration = true;
     }

     if (doMigration)
     {
        var migrationConfig = new DbMigrationsConfiguration<WPH_BusinessContext>();
        migrationConfig.AutomaticMigrationDataLossAllowed = false;
        migrationConfig.AutomaticMigrationsEnabled = true;
        migrationConfig.TargetDatabase = connectionInfo;
        var migrator = new DbMigrator(migrationConfig);
        migrator.Update();
     }

     return context as WPH_BusinessContext;
  }
}  

License

This article, along with any associated source code and files, is licensed under The Code Project Open License (CPOL)