【问题标题】:Entity Framework Automated Migration multiple context实体框架自动迁移多上下文
【发布时间】:2012-09-05 12:30:35
【问题描述】:

我有两个数据库。当我对我的一个 dbcontext 进行更改(添加一个新的 DbSet)时,它应该在运行我的 web 应用程序时自动将更改应用到正确的数据库。所以应该添加新表。因此我添加了两个配置类。每个数据库/上下文一个。

但是,使用下面这样的初始化程序,更改总是应用于第二个上下文/数据库。因为这是配置的最新初始化程序。

Database.SetInitializer(new MigrateDatabaseToLatestVersion<DomainReadModelContext, DomainConfiguration>());
Database.SetInitializer(new MigrateDatabaseToLatestVersion<WebsiteReadModelContext, WebsiteConfiguration>());

我也在web.config中试过

<contexts>
  <context type="Domain.ReadModels.DomainReadModelContext, Domain.ReadModels">
    <databaseInitializer type="System.Data.Entity.MigrateDatabaseToLatestVersion`2[[Domain.ReadModels.DomainReadModelContext, Domain.ReadModels], [Website.Migrations.Domain.DomainConfiguration, Website-WebAppMainModule, Version=1.0.0.0, Culture=neutral]], EntityFramework" />
  </context>
  <context type="Website.ReadModels.WebsiteReadModelContext, Website.ReadModels">
    <databaseInitializer type="System.Data.Entity.MigrateDatabaseToLatestVersion`2[[Website.ReadModels.WebsiteReadModelContext, Website.ReadModels], [Website.Migrations.Website.WebsiteConfiguration, Website-WebAppMainModule, Version=1.0.0.0, Culture=neutral]], EntityFramework" />
  </context>
</contexts

通过包管理器应用更改时,它可以正常工作。该表被添加到我的域上下文数据库中。

Update-Database -config DomainConfiguration

这是因为不支持还是我做错了?现在它似乎只适用于最新注册的初始化程序。

对于更新,我使用包管理器中的 Add-Migration 命令构建了一个迁移。

Add-Migration AddUniquePersonReadModelMigration -config DomainConfiguration

这为我生成了以下课程。

public partial class AddUniquePersonReadModelMigration : DbMigration
{
    public override void Up()
    {
        CreateTable(
            "UniquePersonReadModels",
            c => new
                {
                    Id = c.Guid(nullable: false, identity: true),
                    PersonId = c.Guid(nullable: false),
                    DisplayName = c.String(maxLength: 128),
                })
            .PrimaryKey(t => t.Id)
            .Index(p => p.PersonId)
            .Index(p => p.DisplayName, true);
    }

    public override void Down()
    {
        DropIndex("UniquePersonReadModels", new[] { "PersonId" });
        DropIndex("UniquePersonReadModels", new[] { "DisplayName" });
        DropTable("UniquePersonReadModels");
    }
}

所以我的问题是实体框架是否支持使用初始化程序对多个上下文进行迁移?如果没有,当可以为多个上下文处理迁移时,这将是一个很好的功能。

【问题讨论】:

    标签: entity-framework


    【解决方案1】:

    我通过将 Migration 文件夹从我的网站移动到单独的程序集解决了这个问题。

    所以不是以下内容:

    Solution/
        DomainReadModels/
            DomainContext.cs
            Classes........
        WebsiteReadModels/
            WebsiteContext.cs
            Classes........
        Website/
            Migration/
                AddSomeTableToDomainMigration.cs
                AddSomeTableToWebsiteMigration.cs
                WebsiteReadModelsConfiguration.cs
                DomainReadModelsConfiguration.cs
            Websitefiles...
    

    我将解决方案更改为:

    Solution/
        DomainReadModels/
            Migration/
                DomainReadModelsConfiguration.cs
                AddSomeTableToDomainMigration.cs
            DomainContext.cs
            Classes........
        WebsiteReadModels/
            Migration/
                AddSomeTableToWebsiteMigration.cs
                WebsiteReadModelsConfiguration.cs
            WebsiteContext.cs
            Classes........
        Website/
            Websitefiles...
    

    现在唯一的缺点是我必须在包管理器控制台中切换项目...

    【讨论】:

      【解决方案2】:

      如果我正确理解您的问题,您正在使用两个上下文 DomainReadModelContextWebsiteReadModelContext 并且每个上下文都使用不同的数据库。如果是这种情况,那么您当然可以为每个上下文都有一个初始化程序,并且它将在第一次针对给定数据库使用该上下文时运行。换句话说,DomainReadModelContext 的初始化程序将在 DomainReadModelContext 首次用于域模型数据库时运行,WebsiteReadModelContext 的初始化程序将在 WebsiteReadModelContext 首次用于域时运行模型数据库。

      如果两个上下文都使用同一个数据库,那么这将不起作用。 EF5 不支持对访问同一数据库的多个上下文使用迁移,但我们正在为 EF6 开发它。

      【讨论】:

      • 我使用不同的数据库。设置两个初始化器,但不知何故,表被添加到我的 websiteReadmodelContext 中,它应该被添加到 domainreadmodelcontext 数据库中。
      • 初始化程序在 App_start global.asax 中设置。网站首先点击 websiteReadmodelContext... DomainreadmodelContext 仅在进行更改时才被点击
      • 那么这听起来像是一个错误。如果您可以在 CodePlex (entityframework.codeplex.com/workitem/list/basic) 上创建一个重现并提交一个错误,那就太好了。
      • 只是想澄清一下...设置初始化程序不是触发 init 的原因。这是上下文中的数据库活动。因此,在进行第一次更改之前, DomainReadModelContext 不会触发更新。架构更改当时也没有发生吗?如果它正在发生然后你不想等待,你可以在每个上下文上强制初始化而不等待数据库活动。
      • 在尝试进行更改时也会命中域。将它用于一些跨聚合域验证。所以第一个命中总是一个查询。强迫不是我想要的。只有在必要时才需要这样做。我可以通过在包管理器或一些 SQL 脚本中执行它来强制它。
      猜你喜欢
      • 1970-01-01
      • 2016-07-15
      • 1970-01-01
      • 2012-12-24
      • 1970-01-01
      • 2015-05-11
      • 2018-11-13
      相关资源
      最近更新 更多