Logo Questions Linux Laravel Mysql Ubuntu Git Menu
 

EF Code First MigrateDatabaseToLatestVersion accepts connection string Name from config

While trying to implement EF Migrations in my project I am stuck at one place.

EF Code First MigrateDatabaseToLatestVersion accepts connection string Name from config.

In my case database name get known at Runtime (User selects it from dropdown). Just the way DbContext either accepts, ConnectionString or connectionString Name in it's constructor, "MigrateDatabaseToLatestVersion" does not accept the same

System.Data.Entity.Database.SetInitializer
(new MigrateDatabaseToLatestVersion<SrcDbContext, SRC.DomainModel.ORMapping.Migrations.Configuration>(connString));

Is there any other way to achieve this?

like image 588
Anand Avatar asked Feb 05 '13 15:02

Anand


2 Answers

Thank you all. I did checkout the EF code from codeplex, and inherited my own class after understanding their source code. Here is the solution which I opted :-

public class MigrateDbToLatestInitializerConnString<TContext, TMigrationsConfiguration> : IDatabaseInitializer<TContext>
        where TContext : DbContext
        where TMigrationsConfiguration : DbMigrationsConfiguration<TContext>, new()
    {
        private readonly DbMigrationsConfiguration config;

        /// <summary>
        ///     Initializes a new instance of the MigrateDatabaseToLatestVersion class.
        /// </summary>
        public MigrateDbToLatestInitializerConnString()
        {
            config = new TMigrationsConfiguration();
        }

        /// <summary>
        ///     Initializes a new instance of the MigrateDatabaseToLatestVersion class that will
        ///     use a specific connection string from the configuration file to connect to
        ///     the database to perform the migration.
        /// </summary>
        /// <param name="connectionString"> connection string to use for migration. </param>
        public MigrateDbToLatestInitializerConnString(string connectionString)
        {
            config = new TMigrationsConfiguration
                          {
                              TargetDatabase = new DbConnectionInfo(connectionString, "System.Data.SqlClient")
                          };
        }

        public void InitializeDatabase(TContext context)
        {
            if (context == null)
            {
                throw new ArgumentException("Context passed to InitializeDatabase can not be null");
            }

            var migrator = new DbMigrator(config);

            migrator.Update();
        }
    }

 public static class DatabaseHelper
    {
        /// <summary>
        /// This method will create data base for given parameters supplied by caller.
        /// </summary>
        /// <param name="serverName">Name of the server where database has to be created</param>
        /// <param name="databaseName">Name of database</param>
        /// <param name="userName">SQL user name</param>
        /// <param name="password">SQL password</param>
        /// <returns>void</returns>
        public static bool CreateDb(string serverName, string databaseName, string userName, string password)
        {
            bool integratedSecurity = !(!string.IsNullOrEmpty(userName) || !string.IsNullOrEmpty(password));

            var builder = new System.Data.SqlClient.SqlConnectionStringBuilder
                {
                    DataSource = serverName,
                    UserID = userName,
                    Password = password,
                    InitialCatalog = databaseName,
                    IntegratedSecurity = integratedSecurity,
                };


            var db = new SrcDbContext(builder.ConnectionString);

            var dbInitializer = new MigrateDbToLatestInitializerConnString<SrcDbContext, SRC.DomainModel.ORMapping.Migrations.Configuration>(builder.ConnectionString);

            //following uses strategy to "CreateIfNotExist<>"
            dbInitializer.InitializeDatabase(db);

            return true;

        }
    }
like image 179
Anand Avatar answered Oct 01 '22 10:10

Anand


You can make the MigrateDatabaseToLatestVersion initializer to use the connection string that was used by the context that triggered the migration in the first place. This is done by passing useSuppliedContext: true to the MigrateDatabaseToLatestVersion constructor as described in the docs. In your case:

Database.SetInitializer(new MigrateDatabaseToLatestVersion<SrcDbContext, SRC.DomainModel.ORMapping.Migrations.Configuration>(useSuppliedContext: true));
like image 34
coder925 Avatar answered Oct 01 '22 10:10

coder925