oracle表名和列名默认不区分大小写(未加双引号时自动转大写),但ef core生成的小写/驼峰名与数据库实际大写名不匹配,导致ora-00942或ora-00904;必须在onmodelcreating中统一映射为大写,并用toupper()指定schema名。

Oracle 表名和列名默认区分大小写,EF Core 默认生成小写或驼峰名,不配就会报 ORA-00942 或字段找不到 —— 必须显式统一为大写,且不能依赖“自动转换”。
为什么 Oracle 字段大小写敏感会出错
Oracle 内部把未加双引号的标识符全转成大写,但 EF Core 生成的 SQL 默认用小写/驼峰(如 name、orderDate),导致查询时找不到列;而加了双引号的标识符(如 "name")又强制大小写匹配,一旦实体属性名和数据库实际列名大小写不一致就直接失败。
- 常见错误现象:
ORA-00904: "name": invalid identifier或ORA-00942: table or view does not exist - 根本原因:EF Core 的约定(convention)与 Oracle 的默认行为冲突,不是“配置错”,而是“没覆盖默认行为”
- 关键点:必须让 EF Core 生成的表名、列名和数据库中实际定义的完全一致(通常就是全大写)
在 OnModelCreating 中统一映射为大写
这是最稳定、可复用的方式,避免每个实体都打 [Table] 和 [Column]。
- 对所有表名:用
modelBuilder.Types().Configure(c => c.ToTable(c.ClrType.Name.ToUpper())) - 对所有列名:用
modelBuilder.Properties().Configure(c => c.HasColumnName(c.ClrPropertyInfo.Name.ToUpper())) - 如果用了 Schema(即用户名),必须同时调用
modelBuilder.HasDefaultSchema("YOUR_SCHEMA_NAME".ToUpper()),否则ORA-00942仍会出现 - 注意:这个逻辑必须放在
if (IsOracle)分支里,避免影响其他数据库
连接字符串和驱动版本影响列名解析
Oracle 驱动层(Oracle.EntityFrameworkCore)在不同版本下对大小写的容忍度不同,尤其在早期 5.x 版本中,不指定兼容模式可能跳过大小写标准化步骤。
- 务必在
UseOracle配置中显式声明 SQL 兼容性,例如:b.UseOracleSQLCompatibility("12")(对应 Oracle 12c) - 若用 Oracle 11g,改用
"11",否则某些元数据读取会返回小写列名,导致映射错位 - 确认已安装
Oracle.EntityFrameworkCore(不是旧版Oracle.ManagedDataAccess.EntityFramework),后者不支持 EF Core 5+
实体类上用特性标注的注意事项
如果只对个别表/字段做映射,或团队习惯用特性,需严格按 Oracle 实际定义来写:
-
[Table("PEOPLE")]—— 表名必须全大写,且和SELECT * FROM PEOPLE中的一致 -
[Column("EMP_NAME")]—— 列名也必须全大写,不能写成"emp_name"或"EmpName" - 不要混用:比如
[Table("people")]+[Column("EMP_NAME")],会导致表找不到 - 主键字段也要标注,尤其是自增场景,Oracle 不支持 IDENTITY,常靠序列+触发器,EF Core 需明确知道哪列是主键才能正确生成 INSERT
最容易被忽略的是 Schema 名大小写 —— 它本质就是 Oracle 用户名,必须大写传给 HasDefaultSchema,哪怕连接串里是小写 user id=scott,代码里也得写 HasDefaultSchema("SCOTT")。漏掉这步,哪怕表名列名全对,也会因 schema 解析失败而报 ORA-00942。











