ef core 默认不支持 oracle 命名约定,需手动配置双引号强制大小写、显式映射 snake_case、修正外键列名、控制约束名长度,并人工校验迁移脚本。
ef core 默认不支持 oracle 的命名约定,必须手动干预;直接套用 sql server 的 fororacletotable 或类似 api 会失败,因为 oracle provider(如 oracle.entityframeworkcore)没有内置这些扩展方法。
Oracle 表名和列名大小写敏感问题
Oracle 默认把未加引号的标识符转为大写,而 EF Core 生成的表名/列名默认是 PascalCase 或 camelCase,直接映射会导致找不到对象或报 ORA-00942: table or view does not exist。
- 解决办法是统一用双引号包裹标识符,强制保留大小写 —— 但 EF Core 不会自动加引号,需显式配置
- 在
OnModelCreating中对每个实体调用ToTable("“MyTable”")和HasColumnName("“myColumn”")可行,但维护成本高 - 更稳妥的做法是在模型构建时全局统一加引号:用
modelBuilder.HasAnnotation("Relational:TableName", "“MyTable”")不推荐,它不生效;正确路径是重写IMutableEntityType.GetTableName()的行为 —— 但该方法只读,无法直接改 - 实际可行方案:在
OnModelCreating中遍历所有实体,用entity.ToView("“{name}”")或entity.ToTable("“{name}”"),并逐个处理属性:property.SetColumnName($"“{name}”")
Oracle 不支持小写下划线命名(snake_case)自动转换
EF Core 的 UseSnakeCaseNamingConvention() 是针对 SQL Server/PostgreSQL 设计的,对 Oracle Provider 无效 —— 调用后表名仍为 MyEntity,列名仍为 MyProperty,不会变成 my_entity 或 my_property。
- 如果你的 Oracle 数据库已按 snake_case 建模(如
user_accounts表、created_at列),必须手动映射 - 不要依赖
[Column("created_at")]批量加在每个属性上,容易漏;建议用反射 +modelBuilder遍历自动转换 - 注意 Oracle 对双引号内名称大小写敏感:写
"created_at"和"CREATED_AT"是两个不同列 - 避免混用:同一模型中不要一部分用引号、一部分不用,否则查询时可能因大小写不匹配而静默失败
主键和外键列名不匹配导致迁移失败
Oracle 不允许列名含点号(.)或空格,但 EF Core 默认生成的外键列名如 Order.OrderId 或 OrderID(来自导航属性)可能与已有 Oracle 表结构冲突,执行 dotnet ef migrations add 时会抛出 OracleException: ORA-00904: invalid identifier。
- EF Core 默认按
推导外键列(如OrderOrderId),但在 Oracle 中应改为order_id或"ORDER_ID" - 必须显式配置外键:在
OnModelCreating中用builder.HasOne(x => x.Order).WithMany().HasForeignKey("ORDER_ID") - 如果数据库已有表,别用
HasDefaultValueSql("sysdate")—— Oracle 的sysdate不是字符串,要写成HasDefaultValueSql("SYSDATE")(全大写)且确保列类型是DATE - 主键约束名、索引名也受 Oracle 30 字符限制,自动生成的长名(如
PK_Orders_OrderId_123abc...)会被截断,引发重复名错误;建议用builder.Metadata.SetDefaultName("PK_" + name)控制
真正麻烦的不是怎么加引号,而是 Oracle 的元数据查询(比如 INFORMATION_SCHEMA)和 EF Core 迁移引擎不完全兼容 —— 很多 dotnet ef migrations script 生成的 DDL 在 Oracle 上根本跑不通,必须人工校验每一条 CREATE TABLE 语句里的引号、数据类型、约束语法。这不是配置问题,是 provider 实现深度绑定的问题。











