Click here to Skip to main content
15,867,568 members
Articles / Programming Languages / C#
Tip/Trick

IDbContextFactory which gets Connection String at runtime and triggers Automatic Migrations

Rate me:
Please Sign up or sign in to vote.
0.00/5 (No votes)
4 Feb 2013CPOL 27.8K   4   4
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)


Written By
Software Developer Omicron electronics
Austria Austria
This member doesn't quite have enough reputation to be able to display their biography and homepage.

Comments and Discussions

 
QuestionThank You so much Pin
JUlfeng15-Mar-13 16:29
JUlfeng15-Mar-13 16:29 

General General    News News    Suggestion Suggestion    Question Question    Bug Bug    Answer Answer    Joke Joke    Praise Praise    Rant Rant    Admin Admin   

Use Ctrl+Left/Right to switch messages, Ctrl+Up/Down to switch threads, Ctrl+Shift+Left/Right to switch pages.