4

我想使用我自己构建的 connectionString 执行(代码优先)迁移。

入口点是一个带有一个参数的静态函数,connectionString。

我有一个名为 PocModel 的 DbContext 类,它有两个默认构造函数。

public PocModel() : base("PocModel")
{ ...

以及带有字符串参数的上下文构造函数:

public PocModel(string nameOrConnectionString): base(nameOrConnectionString)
{ ...

我的目标是在连接字符串所针对的数据库上执行迁移,而不是 EF 仅通过名称“神奇地”创建的连接字符串(localhost\sqlexpress - PocModel)。

这是我无法做到的。

我有一个像这样声明的“外部”函数:

public static void MigrateDatabase(string connectionString)
{ ...

我试图在 flw 中实现这个功能。方法:

 DbMigrator migrator = new DbMigrator(new Migrations.Configuration());
 migrator.Configuration.TargetDatabase = new  DbConnectionInfo(connectionString, "System.Data.SqlClient");
 migrator.Update();

像这样:

Database.DefaultConnectionFactory = new SqlConnectionFactory(connectionString);
 Database.SetInitializer<PocModel>(new MigrationInitializer());
 PocModel model = new PocModel(connectionString);
 model.Dispose();

我什至尝试动态设置

ConfigurationManager.ConnectionString["PocModel"]

到传入的connectionString。

但是很遗憾,一切都失败了,并且从 EF 迁移代码中调用了默认的 PocModel 构造函数,目标是 server:localhost\sqlexpress 和 database:PocModel。

我无法迁移到驻留在“localhost\sqlexpress”上的任何未命名为“PocModel”的数据库。

我不能选择使用 app.config 文件来设置我的 connectionString,因为我需要通过静态外部函数将其传入。

请帮助,现在被这个问题困扰了很长时间。

编辑:我已经通过这个 hack 让它工作了,但我问这个问题是为了验证确实没有其他解决方案(也就是 EF 迁移有问题)

  private static string _databaseNameOrConnectionString = "PocModel";

        internal static string DatabaseNameOrConnectionString
        {
            get { return _databaseNameOrConnectionString; }
            //HACK: This setter must ONLY be called from SetupModule.MigrateDatabase. It is a hack to circumvent the code-first migrations usage of this ctor.
            set { _databaseNameOrConnectionString = value; }
        }

        //the code first migrations will call this ctor and ignore the connectionString it have been passed.
        public PocModel()
            : base(DatabaseNameOrConnectionString)
        {
4

3 回答 3

1

Update-database 调用使用默认构造函数,因此您必须修改该函数。您提到您有一个静态类来执行此操作,如果没有静态助手,我无法找到一种方法来完成这项工作。

 public static class Helper
    {
        public static string GetConnectionString()
        {
            SqlConnectionStringBuilder builder = new SqlConnectionStringBuilder();
            builder.DataSource = @".\sqlexpress";
            builder.InitialCatalog = "migrateme";
            builder.IntegratedSecurity = true;
            builder.MultipleActiveResultSets = true;
            return builder.ConnectionString;
        }
    }

然后我没有调用基本构造函数,而是使用自定义字符串调用构造函数,它创建了正确的数据库

public PocModel() : base(Helper.GetConnectionString())
{ 

}
于 2012-08-08T12:44:53.230 回答
0

我和你有同样的问题。但是,我找到了一个解决方案,您说您尝试过但没有奏效。以下代码确实对我有用。我在这里找到它http://romiller.com/2012/02/09/running-scripting-migrations-from-code/

var configuration = new Configuration();
configuration.TargetDatabase = new DbConnectionInfo("Server=MyServer;Database=MyDatabase;Trusted_Connection=True;", 
    "System.Data.SqlClient");
var migrator = new DbMigrator(configuration);
migrator.Update();
于 2013-03-07T14:39:32.913 回答
0

对于那些发现他们的连接字符串被忽略的人......

框架的这一部分似乎存在错误

var configuration = new TMigrationsConfiguration();
configuration.TargetDatabase = new DbConnectionInfo(context.Database.Connection.ConnectionString,"System.Data.SqlClient");
var migrator = new DbMigrator(configuration);
migrator.Update();

行为不一样

var configuration = new TMigrationsConfiguration();
var migrator = new DbMigrator(configuration);
migrator.Configuration.TargetDatabase = new DbConnectionInfo(context.Database.Connection.ConnectionString,"System.Data.SqlClient");
migrator.Update();

也就是说 - 如果在创建迁移器后更改了目标数据库,则会忽略目标数据库。您必须在添加到迁移器之前设置 TargetDatabase。

于 2013-06-22T12:24:09.290 回答