Entity framework 4 EF 4.3一个数据库中具有多个DBContext的自动迁移

Entity framework 4 EF 4.3一个数据库中具有多个DBContext的自动迁移,entity-framework-4,entity-framework-migrations,Entity Framework 4,Entity Framework Migrations,我正在尝试将EF4.3迁移与多个代码优先的DBContext一起使用。我的应用程序分为几个插件,这些插件可能有自己的域DbContext。应用程序应该使用一个sql数据库 当我尝试在空数据库中自动迁移上下文时,这只在第一个上下文中成功。其他所有上下文都需要将AutomaticMiggerationDataLossAllowed属性设置为true,然后尝试删除前一个上下文的表 所以我的问题是: 我如何告诉迁移配置只关注在其相应上下文中定义的表,而不去管其他表 在一个数据库中通过自动迁移处理多个D

我正在尝试将EF4.3迁移与多个代码优先的DBContext一起使用。我的应用程序分为几个插件,这些插件可能有自己的域DbContext。应用程序应该使用一个sql数据库

当我尝试在空数据库中自动迁移上下文时,这只在第一个上下文中成功。其他所有上下文都需要将AutomaticMiggerationDataLossAllowed属性设置为true,然后尝试删除前一个上下文的表

所以我的问题是:

  • 我如何告诉迁移配置只关注在其相应上下文中定义的表,而不去管其他表
  • 在一个数据库中通过自动迁移处理多个DBContext的正确工作流是什么

谢谢大家!

代码优先迁移假定每个数据库只有一个迁移配置(每个配置有一个上下文)

我可以想出两种可能的解决办法:

  • 创建包含每个上下文的所有实体的聚合上下文,并从您的migrations配置类引用此“超级”上下文。这样,所有的表都将在用户的数据库中创建,但数据将只在他们为其安装插件的表中

  • 对每个上下文使用单独的数据库。如果您在上下文之间共享了实体,请添加自定义迁移,并将
    CreateTable(…)
    调用替换为
    Sql(“创建视图…”)
    调用,以从实体的“原始”数据库获取数据


  • 我会尝试1,因为它将所有内容都保存在一个数据库中。您可以在解决方案中创建一个单独的项目来包含迁移和这个“超级”上下文。只需添加项目,引用所有插件的项目,创建包含所有实体的上下文,然后在此新项目上调用Enable Migrations。在那之后,一切都应该按预期进行。

    我有一个使用迁移的具有多个上下文的工作站点。但是,您确实需要为每个上下文使用一个单独的数据库,并且它都是由项目迁移命名空间中的*配置类驱动的,因此,例如CompanyDbContext使用CompanyConfiguration指向Company.sdf<代码>更新数据库-配置类型名称公司配置。另一个LogDbContext使用LogConfiguration等指向Log.sdf

    考虑到这一点,您是否尝试过创建两个指向同一数据库的上下文,并告诉modelbuilder忽略其他上下文的表列表

    protected override void OnModelCreating(DbModelBuilder modelBuilder)
    {
        modelBuilder.Ignore<OtherContextsClass>();
        // more of these
    }
    
    模型创建时受保护的覆盖无效(DbModelBuilder modelBuilder)
    {
    Ignore();
    //更多这些
    }
    
    因为迁移是与ModelBuilder一起工作的,所以这可能会完成这项工作


    糟糕的选择是避免使用自动迁移,每次生成迁移,然后手动筛选并删除不需要的语句,然后运行它们,尽管没有什么能阻止您创建一个简单的工具来查看上下文和生成的语句,并为您进行迁移修复。

    以下是您可以做的。很简单

    您可以为每个上下文创建配置类。 e、 g

    这将为context1创建迁移脚本。您可以在其他上下文中重复此操作

    Add-Migration -configuration Configuration2 Context2Init
    
    更新数据库的步骤

    Update-Database -configuration Configuration1
    Update-Database -configuration Configuration2
    

    这可以按任何顺序进行。除非您需要确保按顺序调用每个配置。

    我已经让它使用手动迁移,但是您不能降级,因为它不能在u MigrationHistory表中区分不同的配置。如果我尝试降级,那么它会将来自其他配置的迁移视为自动迁移,因为我不允许数据丢失,所以会失败。我们将永远只会使用它来升级,虽然这样它为我们的目的工作


    不过,这看起来确实有点不理想,我相信只要DBContext之间没有重叠,就不难支持它。

    好的,我已经为此奋斗了一天,下面是为那些寻求答案的人提供的解决方案

    Add-Migration -configuration Configuration2 Context2Init
    
    我假设读这篇文章的大多数人都在这里,因为他们有一个很大的DbContext类,有很多DbSet属性,而且加载需要很长时间。你可能会想,哎呀,这是有道理的,我应该分割上下文,因为我不会同时使用所有的数据库集,我只会根据需要加载“部分”上下文。因此,您将它们分开,结果发现代码优先迁移不支持您的革命性思维方式

    因此,第一步必须是拆分上下文,然后为每个新上下文添加MigrationConfiguration类,添加与新上下文类名称完全相同的连接字符串

    然后,您尝试逐个运行新拆分的上下文,方法是添加迁移上下文1,然后更新数据库-详细

    一切似乎都很正常,但随后您注意到,每次后续迁移都会删除上一次迁移中的所有表,而只保留上一次迁移中的表

    这是因为,当前的迁移模型要求每个数据库有一个DbContext,并且必须是镜像匹配

    我也尝试过,有人建议我这样做,就是创建一个超级上下文,里面有所有的数据库集。创建单个迁移配置类并在中运行该类。保留部分上下文类,并尝试实例化和使用它们。EF抱怨支持模式已经改变。同样,这是因为EF将部分dbcontext与超级上下文迁移留下的All Set上下文签名进行比较

    在我看来,这是一个重大缺陷

    就我而言,我认为性能比迁移更重要。所以
    Update-Database -configuration Configuration1
    Update-Database -configuration Configuration2
    
    internal sealed class Configuration1 : DbMigrationsConfiguration<Context1>{
           public Configuration1 (){
            AutomaticMigrationsEnabled = false;
            MigrationsNamespace = "YourProject.Models.ContextNamespace1";
       }
     }
    
    internal sealed class Configuration2 : DbMigrationsConfiguration<Context2>{
       public Configuration2 (){
            AutomaticMigrationsEnabled = false;
            MigrationsNamespace = "YourProject.Models.ContextNamespace2";
       }
    }
    
    internal sealed class Configuration1 : DbMigrationsConfiguration<Context1>{
           public Configuration1 (){
            AutomaticMigrationsEnabled = false;
       }
     }
    
    internal sealed class Configuration2 : DbMigrationsConfiguration<Context2>{
       public Configuration2 (){
            AutomaticMigrationsEnabled = false;
       }
    }