我在使用针对 Oracle 数据库的实体框架迁移时遇到了麻烦,因为架构名称包含在迁移代码中,并且对于 Oracle,架构名称也是用户名。我的目标是拥有独立于模式的 Code First 迁移(能够拥有一组用于测试和生产环境的迁移)。
我已经尝试过这种方法(使用实体框架 6.1.3):
1)我在 Web.config 中有架构名称:
<add key="SchemaName" value="IPR_TEST" />
2)我的DbContext将模式名称作为构造函数参数:
public EdistributionDbContext(string schemaName)
: base("EdistributionConnection")
{
_schemaName = schemaName;
}
protected override void OnModelCreating(DbModelBuilder modelBuilder)
{
modelBuilder.HasDefaultSchema(_schemaName);
}
3)我必须为实体框架迁移实现 IDbContextFactory 才能创建没有无参数构造函数的 DbContext:
public class MigrationsContextFactory : IDbContextFactory<EdistributionDbContext>
{
public EdistributionDbContext Create()
{
return new EdistributionDbContext(GetSchemaName());
}
}
4)我还配置了迁移历史表以放置在正确的架构中:
public class EdistributionDbConfiguration : DbConfiguration
{
public EdistributionDbConfiguration()
{
SetDefaultHistoryContext((connection, defaultSchema)
=> new HistoryContext(connection, GetSchemaName()));
}
}
5)我修改了为迁移生成的代码以替换硬编码的架构名称。例如。我更换了CreateTable("IPR_TEST.Users")
with CreateTable($"{_schema}.Users")
. (_schema
字段根据 Web.config 中的值设置)。
6)我用MigrateDatabaseToLatestVersion<EdistributionDbContext, MigrationsConfiguration>()
数据库初始化程序。
设置完所有这些后,当我切换到不同的模式(例如,通过 web.config 转换)时,我仍然遇到问题 - 抛出一个异常,告诉我数据库与我的模型不匹配,并且自动迁移被禁用(这是所需的)。当我尝试执行时add-migration
生成新的迁移,其中所有对象都应移动到不同的架构(例如:MoveTable(name: "IPR_TEST.DistSetGroups", newSchema: "IPR");
,这绝对是不希望的。
对我来说,模式名称似乎是硬连接在迁移类中的模型字符串哈希中的某个位置(例如 201509080802305_InitialCreate.resx),即:
<data name="Target" xml:space="preserve">
<value>H4sIAAAAAAAEAO09227jO... </value>
</data>
有没有办法告诉 Code First 迁移忽略架构名称?