ora-00904 报错在 ef core + oracle 场景下几乎总是因字段名大小写不匹配或保留字未加双引号所致,需通过 user_tab_columns 确认真实列名并统一使用双引号显式指定。

ORA-00904 报错在 EF Core + Oracle 场景下,**几乎总是因为字段名大小写不匹配或保留字未加引号导致的**,而不是 EF Core 本身有问题。Oracle 的解析规则和 .NET 的默认映射行为存在隐式冲突,必须手动对齐。
EF Core 生成的 SQL 字段名 vs Oracle 实际列名大小写不一致
Oracle 在未用双引号建表时,会把所有列名转为大写;但如果你用双引号建了小写字段(比如 "pwd"),那查询时就必须用 "pwd",不能写 pwd 或 PWD。EF Core 默认生成的 SQL 不带双引号,所以一查就崩。
- 检查表定义:
SELECT column_name FROM user_tab_columns WHERE table_name = 'YOUR_TABLE',看字段名是否带双引号(即大小写敏感) - 如果结果里显示的是
PWD,说明是大写字段 → EF Core 实体属性名用Pwd或PWD都行,但映射时别加双引号 - 如果结果里显示的是
"pwd"(含引号),说明是小写字段 → 必须让 EF Core 生成带双引号的字段引用 - 在实体配置中强制指定列名:
builder.Property(x => x.Pwd).HasColumnName("pwd")不够,得写成.HasColumnName("\"pwd\"")(注意转义)
Oracle 保留字被用作字段名(如 order、group、desc)
EF Core 不会自动给保留字加双引号,而 Oracle 要求必须加。比如你有个字段叫 order,EF Core 生成 WHERE order = 1 就直接报 ORA-00904。
- 最稳妥的做法:改字段名,避开
ORDER、GROUP、LEVEL、USER等常见保留字 - 临时绕过:在 Fluent API 中显式加双引号:
.HasColumnName("\"order\"") - 验证是否为保留字:
SELECT * FROM v$reserved_words WHERE keyword = 'ORDER'(区分大小写,查大写)
EF Core 迁移生成的表结构与手动建表不一致
如果你先用 EF Core Migration 创建了表,又手动用 PL/SQL 工具(如 SQL Developer)执行了带双引号的 DDL(例如 CREATE TABLE t ("id" NUMBER)),那这张表实际字段就是 "id",但 EF Core 仍按 ID 去查 —— 看似一样,实则 Oracle 认为这是两个不同标识符。
- 迁移生成的表默认全大写字段,不要在 DDL 里加双引号
- 如果已有双引号字段,别指望 EF Core 自动适配;要么重建表(
DROP TABLE t; CREATE TABLE t (id NUMBER)),要么统一在所有HasColumnName中补双引号 - 特别注意视图或同义词场景:EF Core 查询视图时,视图底层 SELECT 的字段若用了双引号,也得同步处理
Oracle 19c+ 中 WM_CONCAT 等函数被移除引发的 ORA-00904
这不是字段问题,而是你在 EF Core 的原始 SQL 或数据库视图里调用了 WMSYS.WM_CONCAT,而 Oracle 19c 默认不启用 WMSYS 或该函数已被废弃。
- 错误典型表现:
ORA-00904: "WMSYS"."WM_CONCAT": 标识符无效 - 不要试图解锁 WMSYS 用户或重建函数 —— 这违反 Oracle 最佳实践且有安全风险
- 改用标准替代方案:
LISTAGG(col, ',') WITHIN GROUP (ORDER BY ...) - 如果必须兼容旧逻辑,封装成自定义函数(放在业务用户下,不用 WMSYS),再在 EF Core 中调用新函数名
真正麻烦的不是报错本身,而是 Oracle 对大小写和引号的“静默转换”机制 —— 它不会告诉你“你写的 pwd 和我存的 'pwd' 不是一回事”,只会甩你一个模糊的 ORA-00904。查的时候一定要盯死 user_tab_columns.column_name 的真实值,而不是靠肉眼猜。











