在 EntityFramework Code First 迁移中覆盖“dbo”模式名称
Posted
技术标签:
【中文标题】在 EntityFramework Code First 迁移中覆盖“dbo”模式名称【英文标题】:Override "dbo" schema name in EntityFramework Code First Migrations 【发布时间】:2017-12-02 07:03:43 【问题描述】:我正在尝试使用 EntityFramework Codefirst 和 Oracle 数据库创建一个独立于模式的模型,但 EF 将迁移 dbo 用作模式的默认值。 我在我的 DBContext 上覆盖了 OnModelCreating 方法来解决这个问题,并在 connectionString 中使用用户来代替
protected override void OnModelCreating(DbModelBuilder modelBuilder)
base.OnModelCreating(modelBuilder);
modelBuilder.HasDefaultSchema(string.Empty);
问题是 __MigrationHistory 忽略了这个默认架构,并且在运行第一次迁移时出现此错误:
ORA-01918: 用户 'dbo' 不存在
尝试this msdn entry 自定义此表的架构。
CustomHistoryContext:
public class CustomHistoryContext : HistoryContext
public CustomHistoryContext(DbConnection dbConnection, string defaultSchema)
: base(dbConnection, defaultSchema)
protected override void OnModelCreating(DbModelBuilder modelBuilder)
base.OnModelCreating(modelBuilder);
modelBuilder.HasDefaultSchema(String.Empty);
和 DBConfiguration:
public sealed class Configuration :
DbMigrationsConfiguration<Model.MyDbContext>
public Configuration()
AutomaticMigrationsEnabled = false;
SetHistoryContextFactory("Oracle.ManagedDataAccess.Client",
(connection, defaultSchema) => new CustomHistoryContext(connection, defaultSchema));
protected override void Seed(Model.Model1 context)
并且在第一次迁移时工作正常。但是当我修改我的实体模型并尝试使用add-migration
命令反映此更改时,我收到以下错误:
无法生成显式迁移,因为以下原因 显式迁移待定:[201706281804589_initial, 201706281810218_pp2]。在之前应用挂起的显式迁移 尝试生成新的显式迁移。
看起来 EF 丢失了,此时无法找到迁移历史记录。
当我在 Configuration
中评论 SetHistoryContextFactory
指令时,它适用于后续的 add-migration
命令,但是当我想从头开始运行所有迁移(例如部署)时,这种解决方法还不够。
有谁知道我是否可以很好地完成此任务,或者是否有更好的解决方法?
【问题讨论】:
您使用的是哪个 Oracle 提供商?可能是 Oracle 提供程序没有实现此功能的问题。如果您可以快速访问它,也许可以使用 SQL Server 快速尝试一下,看看结果是否相同?此外,不确定是否提供 string.Empty 架构使其默认为嵌入式默认值 (dbo)。 嗨@MichaelWeinand,感谢您的快速评论。我正在使用 Nuget 包中的 Oracle.ManagedDataAccess.EntityFramework v12.1.2400。尝试使用 SQL Server,但string.Empty
用于 MyDBcontext
架构名称和 sql 脚本是可以的,但对于 CustomHistoryContext
生成的 sql 插入历史中的第一个迁移是:INSERT [CodeFirstDatabase].[__MigrationHistory]([MigrationId], [ContextKey], [Model], [ProductVersion])...
注意 CodeFirstDatabase 架构名称
不幸的是,SQL Server 和 Oracle 在架构是什么以及如何与之交互方面的概念略有不同。我猜 [CodeFirstDatabase] 名称是一个内置的默认值,如果你传入 string.Empty 就会使用它。您实际上想将其设置为什么?即使在 Oracle 中,我也不确定您是否真的不能提供模式名称?
一个简化的教程可以在这里找到:oracle.com/webfolder/technetwork/tutorials/obe/db/dotnet/…
@oskr 嘿,我也有同样的问题。以下答案是否为您解决了问题,或者您是否找到了其他解决方案 - 干杯
【参考方案1】:
转到 Migrations -> Configuration.cs 和下面提到的代码。这个修复对我有用!
class Configuration : DbMigrationsConfiguration<CodeFirstOracleProject.Context>
public Configuration()
AutomaticMigrationsEnabled = false;
var historyContextFactory = GetHistoryContextFactory("Oracle.ManagedDataAccess.Client");
SetHistoryContextFactory("Oracle.ManagedDataAccess.Client",
(dbc, schema) => historyContextFactory.Invoke(dbc, "YourSchemaName"));
【讨论】:
【参考方案2】:再次尝试运行Enable-Migrations -force。然后运行 Add-Migration SomeDescription –IgnoreChanges。之后,运行“Update-Database - Verbose”。这对我有用
【讨论】:
【参考方案3】:我在 Oracle 的 Configuration : DbMigrationsConfiguration
类中成功尝试了以下操作,以便将历史模式更改为“测试”:
var historyContextFactory = GetHistoryContextFactory("Oracle.ManagedDataAccess.Client");
SetHistoryContextFactory("Oracle.ManagedDataAccess.Client",
(dbc, schema) => historyContextFactory.Invoke(dbc, "Test"));
所以基本上,我没有尝试使用未更改的默认架构注册自定义历史上下文,而是尝试使用更改的默认架构注册默认历史上下文。
结果:当我运行Update-Database -Script
时,生成的脚本包含用于创建__MigrationHistory
表以及插入新历史值的新模式:
create table "Test"."__MigrationHistory"
-- ...
insert into "Test"."__MigrationHistory"("MigrationId", "ContextKey", "Model", "ProductVersion") ...
但是,让我们非常清楚:我只是尝试了我期望通过直觉工作的东西,它确实对我有用。我没有找到任何可靠的文档来支持此解决方案。
【讨论】:
【参考方案4】:打开 Migrations -> Configuration.cs 并添加
public Configuration()
AutomaticMigrationsEnabled = false;
var historyContextFactory = GetHistoryContextFactory("Oracle.ManagedDataAccess.Client");
SetHistoryContextFactory("Oracle.ManagedDataAccess.Client",
(dbc, schema) => historyContextFactory.Invoke(dbc, "your_schema_name_hear"));
【讨论】:
以上是关于在 EntityFramework Code First 迁移中覆盖“dbo”模式名称的主要内容,如果未能解决你的问题,请参考以下文章
EntityFramework Code-First 简易教程-------领域类配置之DataAnnotations
EntityFramework Code First 模式下使用数据迁移
EntityFramework Reverse POCO Code First 生成器
在 EntityFramework Code First 迁移中覆盖“dbo”模式名称