15

在我的项目中尝试实施 EF 迁移时,我被困在一个地方。

EF Code First MigrateDatabaseToLatestVersion 接受来自配置的连接字符串名称。

在我的情况下,数据库名称在运行时被知道(用户从下拉列表中选择它)。就像 DbContext 在其构造函数中接受 ConnectionString 或 connectionString Name 一样,“MigrateDatabaseToLatestVersion”不接受相同的

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

有没有其他方法可以实现这一目标?

4

4 回答 4

14

谢谢你们。我确实从 codeplex 签出了 EF 代码,并在理解他们的源代码后继承了我自己的类。这是我选择的解决方案:-

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;

        }
    }
于 2013-04-23T07:30:20.357 回答
7

您可以使MigrateDatabaseToLatestVersion初始化程序使用最初触发迁移的上下文所使用的连接字符串。这是通过将useSuppliedContext: true传递给 MigrateDatabaseToLatestVersion 构造函数来完成的,如文档中所述。在你的情况下:

Database.SetInitializer(new MigrateDatabaseToLatestVersion<SrcDbContext, SRC.DomainModel.ORMapping.Migrations.Configuration>(useSuppliedContext: true));
于 2017-06-02T12:11:55.210 回答
3

这是在什么背景下运行的?网站或桌面应用程序?

在网站下,这样做不是一个好主意。针对上下文类型设置的数据库初始化策略。因此具有相同类型上下文的不同连接字符串将覆盖彼此的初始化策略。

如果是桌面应用程序,可能包含一个额外的实用程序来在数据库之间切换?

无论哪种方式,我都不建议这样做,但如果你真的想做你提到的事情,看起来你必须破解它。

    using (var context = new DbContext("<Your connection string right in here>"))
    {
        var constructors = typeof (DbMigrator).GetConstructors(BindingFlags.Instance | BindingFlags.NonPublic);
        var hackedDbMigrator = constructors[0].Invoke(new object[] { new Configuration(), context }) as DbMigrator;
        hackedDbMigrator.Update();
    }
于 2013-04-19T06:57:38.773 回答
0

这是迁移调用带有参数的 DbContext 派生类的问题。一旦解决了这个问题,它应该可以工作。有关示例解决方案,请参见此处。 EntityFramework 代码优先自定义连接字符串和迁移

于 2013-04-22T07:00:43.693 回答