繁体   English   中英

实体框架代码首先确定数据库是否兼容

[英]Entity Framework code first determine if a Database is compatible

我们的项目包含两个使用相同模型访问相同数据库的应用程序。 这两个应用程序使用相同的引导机制,如果数据库与模型不兼容,它将删除数据库并重新创建它。 它使用以下代码:

    private bool DropCreateDatabaseIfModelChanged(TContext context)
    {
        if (context.Database.Exists())
        {
            if (context.Database.CompatibleWithModel(throwIfNoMetadata: true))
            {
                return false;
            }

            context.Database.Delete();
        }

        var createDatabaseCollationInterceptor = new CreateDatabaseCollationInterceptor(Constants.Database.COLLATION);
        DbInterception.Add(createDatabaseCollationInterceptor);
        context.Database.Create();
        DbInterception.Remove(createDatabaseCollationInterceptor);

        return true;
    }

第二个应用程序仅使用第一个应用程序的模型的子集,并且在调用上述函数context.Database.CompatibleWithModel(throwIfNoMetadata: true)返回false并删除数据库。

如果满足以下条件,则CompatibleWithModel返回true:

For Code First the model is considered compatible if the model is stored in the database in the Migrations history table and that model has no differences from the current model as determined by Migrations model differ

问题 :如果模型仅包含整个模型的一个子集,我如何确定该模型是否兼容(据我所知)?

[编辑]关于体系结构的一些话

  • 应用程序1公开了RESTful API(由前端使用)
  • 应用程序2公开SOAP端点(为此创建第二个应用程序的原因是不混合堆栈)
  • 应用程序1由5个模块组成(一个模块是一个逻辑功能,涵盖从数据访问到UI的整个堆栈)
  • 应用程序2引用了应用程序1的2个模块(仅它需要的模块)
  • 模块没有引用其他模块的实体
  • 一个通用的数据库上下文被用来初始化数据库,同时保持实体定义彼此分离。 除通用基本模块外的所有模块均如此

[Edit2]添加了描述使用SharedTables进行应用程序交互的工作流 在此处输入图片说明

首先使用代码时,使同一个数据库上的多个模型同居的最简单方法是使用单独的迁移历史表

链接的文章中的TL; DR:对于每个单独的模型,创建一个这样的新类

using System.Data.Common;
using System.Data.Entity;
using System.Data.Entity.Migrations.History;

namespace CustomizableMigrationsHistoryTableSample
{
    public class MyHistoryContext : HistoryContext
    {
        public MyHistoryContext(DbConnection dbConnection, string defaultSchema)
            : base(dbConnection, defaultSchema)
        {
        }

        protected override void OnModelCreating(DbModelBuilder modelBuilder)
        {
            base.OnModelCreating(modelBuilder);
            // "MigrationHistory" would have to be renamed for each subset model
            modelBuilder.Entity<HistoryRow>().ToTable(tableName: "MigrationHistory", schemaName: "admin");
            modelBuilder.Entity<HistoryRow>().Property(p => p.MigrationId).HasColumnName("Migration_ID");
        }
    }
}

并将其添加到您的设置中:

using System.Data.Entity;

namespace CustomizableMigrationsHistoryTableSample
{
    public class ModelConfiguration : DbConfiguration
    {
        public ModelConfiguration()
        {
            this.SetHistoryContext("System.Data.SqlClient",
                (connection, defaultSchema) => new MyHistoryContext(connection, defaultSchema));
        }
    }
}

我已使用此方法将有限接口(即前端/公共api)的运行时与管理接口(后端api)强烈分离,以限制错误/攻击面。 我建议对模型的子集进行某种代码共享,以避免架构漂移。

我从未尝试过这是您的特定情况(完全删除不兼容的数据库),因此可能需要进行一些调整。 在将单独的模型(至少是子集模型)设置到现有数据库时,您将需要执行类似Add-Migration Initial -IgnoreChanges操作,有关更多信息,请参见此问题

暂无
暂无

声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM