我们的项目包含两个使用相同模型访问同一数据库的应用程序。 两个应用程序都使用相同的引导机制,如果数据库与模型不兼容,它将删除数据库并重新创建它。它使用以下代码:
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
问题:如果模型只包含整个模型的子集,我怎样才能确定模型是否兼容(我知道它是什么)?
[编辑]关于架构的一些话
答案 0 :(得分:0)
首先使用代码时,最简单的方法是在同一个数据库中启用多个模型共同使用separate migration history tables。
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)强烈分开,以限制bug /攻击面。我建议在模型子集上进行某种代码共享,以避免模式漂移。
我从未尝试过这是您的特定情况(完全丢弃不兼容的数据库),因此可能需要进行一些调整。在为现有数据库设置单独的模型(至少是子集模型)时,您需要执行Add-Migration Initial -IgnoreChanges
之类的操作,有关详细信息,请参阅this question。