Entity Framework代码优先迁移到多个数据库

3

假设我们有一个Web应用程序的架构模型,每个帐户都有1个数据库。这些帐户的数据库结构相同,只有其中的数据不同。如何在Code First模型中配置迁移。


你为不同的账户有不同的发布分支吗? - Newton Sheikh
不,它们只有一个发布分支。 - Vitach
3个回答

8
现在我有下一个解决方案。 可以在主方法或者global.asax中添加以下内容:
    var migration_config = new Configuration();
    migration_config.TargetDatabase = new DbConnectionInfo("BlogContext");
    var migrator = new DbMigrator(migration_config);
    migrator.Update();
    migration_config.TargetDatabase = new DbConnectionInfo("BlogContextCopy");
    migrator = new DbMigrator(migration_config);
    migrator.Update();

在 app_config 文件中的连接字符串示例:

<connectionStrings>
 <add name="BlogContext" providerName="System.Data.SqlClient" connectionString="Server=(localdb)\v11.0;Database=MigrationsDemo.BlogContext;Integrated Security=True;"/>
 <add name="BlogContextCopy" providerName="System.Data.SqlClient" connectionString="Server=(localdb)\v11.0;Database=MigrationsDemo.BlogContextCopy;Integrated Security=True;"/>
</connectionStrings>

配置类和上下文:

internal sealed class Configuration : DbMigrationsConfiguration<MigrationsDemo.BlogContext>
{
    public Configuration()
    {
        AutomaticMigrationsEnabled = true;
        AutomaticMigrationDataLossAllowed = true;
    }

    protected override void Seed(MigrationsDemo.BlogContext context) {
    }
}

public class BlogContext : DbContext {
    public BlogContext() {}
    public BlogContext(string connection_name) : base(connection_name) {
    }
    public DbSet<Blog> Blogs { get; set; }
}

2
除了您出色的答案之外,您可以使用外部配置文件(即“clients.json”)而不是硬编码它们,将所有数据库信息以键值对的形式放入json文件中,并在启动时加载它。
然后,通过迭代键值对,您可以进行初始化。 clients.json 文件内容:
{
  "DatabaseA": "DatabaseAConnectionString",
  "DatabaseB": "DatabaseBConnectionString",
  "DatabaseC": "DatabaseCConnectionString",
  ...
}

提供一种处理迁移的方法:
public static void MigrateDatabases(IDictionary<string,string> databaseConfigs)
{
  foreach (var db in databaseConfigs)
  {
    var config = new Configuration
    {
      TargetDatabase = new DbConnectionInfo(db.Value, "System.Data.SqlClient")
    };

    var migrator = new DbMigrator(config);
    migrator.Update();
  }
}

然后在启动过程中(我使用OWIN,所以在我的Startup.cs文件中,也可以是global.asax.cs文件):

string json;
var path = HttpRuntime.AppDomainAppPath;
using (var reader = new StreamReader(path + @"Config\clients.json"))
{
   json = reader.ReadToEnd();
}

var databases = JsonConvert.DeserializeObject<IDictionary<string, string>>(json);
MigrateDatabases(databases);

对我来说非常好用 :)

0

请查看应用程序启动期间自动迁移页面

如果您使用此方法应用迁移,您可以使用任何连接字符串(或其他方法来准确标识要连接的数据库),并在连接时执行迁移。


如何通知迁移工具我需要更新的数据库列表?你能给一些例子吗? - Vitach
如果我在连接字符串部分输入大约50或100个数据库,迁移工具将如何知道哪些需要进行迁移? - Vitach
Database.SetInitializer(new MigrateDatabaseToLatestVersion<BlogContext, Configuration>())无法工作,因为它只能更新一个数据库。 - Vitach
你的应用程序通常如何知道连接哪个数据库?这应该会自动迁移你连接到的任何数据库。 - Steve
@Steve,我也有一款多租户应用程序,我们有一个单一的Web应用程序,每个客户都有一个数据库。我们有一个租户初始化器,在运行时确定将哪个数据库名称注入到连接字符串中(对我们而言,它基于子域)。所以,我和你面临同样的问题,如何告诉迁移执行者循环遍历一系列连接字符串或DbContexts? - clockwiseq
1
@Keith,自从我上次使用EF以来已经很长时间了。我不确定如何遍历所有连接,但如果您只是连接到每个数据库并执行一些简单的查询,它将迁移到新模式。 - Steve

网页内容由stack overflow 提供, 点击上面的
可以查看英文原文,
原文链接