直接使用 Oracle.EntityFrameworkCore 8.21.0+ 配合完整 DESCRIPTION 连接字符串、显式 UseOracleSQLCompatibility("19")、[Table("NAME", Schema="SCHEMA")] 映射及 NLS 参数校准,即可在 .NET 8 下稳定运行。

直接用 Oracle.EntityFrameworkCore 8.x 版本,配合完整连接字符串和显式 SQL 兼容性配置,就能跑通。别装 Oracle.ManagedDataAccess.Core 单独包,它和 EF Core 提供程序冲突;也别信“只改 appsettings.json 就行”的说法——Oracle 的大小写、Schema、NLS 参数不处理,查不出数据是常态。
确认 NuGet 包版本与 .NET 8 兼容性
EF Core 8 要求 Oracle 提供程序必须是 Oracle.EntityFrameworkCore ≥ 8.21.0(2025 年后发布的正式版),不能用 2.x / 3.x / 5.x 等旧版——它们只支持 EF Core 2.1–5.0,运行时会报 MethodNotFoundException 或 MissingMethodException。
- 在项目中执行:
dotnet add package Oracle.EntityFrameworkCore --version 8.21.0 - 检查是否自动拉取了
Oracle.ManagedDataAccess(非 Core 版)——如果有,手动删掉Oracle.ManagedDataAccess.Core引用,避免双驱动共存 - 不需安装 Oracle 客户端、ODP.NET、tnsnames.ora 或 Visual Studio Tools
连接字符串必须写死 DESCRIPTION 格式,不能用简写
Data Source=host:port/service_name 这种写法在 .NET 8 + Oracle 21c/19c 上大概率失败,错误是 ORA-12154: TNS could not resolve the connect identifier,哪怕 tnsnames.ora 存在且正确。
- 必须用完整 DESCRIPTION 连接串:
Data Source=(DESCRIPTION=(ADDRESS=(PROTOCOL=TCP)(HOST=192.168.1.100)(PORT=1521))(CONNECT_DATA=(SERVICE_NAME=ORCLPDB1)));User Id=hr;Password=hr; - 如果数据库启用了 PDB,
SERVICE_NAME必须指向 PDB 名(不是 CDB 名),否则连上的是空容器,DbSet查询返回空列表但无报错 - 加
Persist Security Info=True可避免某些环境下的认证缓存干扰,开发阶段建议加上
OnConfiguring 中必须指定 UseOracleSQLCompatibility
不设兼容模式,EF Core 8 生成的 SQL 会用 OFFSET ... FETCH NEXT 分页语法,而 Oracle 12c 之前不支持;即使连的是 19c,若未声明,提供程序仍可能降级生成 ROWNUM 套壳语句,导致分页错位或全表扫描。
- 在
OnConfiguring里这样写:optionsBuilder.UseOracle(connectionString, b => b.UseOracleSQLCompatibility("19")) -
"11"对应 11g,"12"对应 12c,"19"对应 19c/21c/23ai —— 必须跟实际数据库主版本一致,不能填 "8" 或 "latest" - 这个参数影响
ORDER BY+LIMIT、序列(IDENTITY)、JSON函数等行为,漏设会导致迁移失败或查询结果异常
实体类和表名映射必须用 [Table] + 大写 + 显式 Schema
Oracle 默认把未加引号的标识符转成大写,而 EF Core 8 的默认约定是小写蛇形命名。不干预就会出现 ORA-00942: table or view does not exist,即使表真实存在。
- 实体类上加:
[Table("EMPLOYEES", Schema = "HR")]——Schema不可省略,否则默认找当前用户同名 schema,多数情况不是你想要的 - 字段用
[Column("EMPLOYEE_ID")],不能依赖属性名自动映射 - 如果 DBA 给的是小写带引号的表名(如
"employees"),则[Table("\"employees\"")],但强烈建议让 DBA 改为大写无引号,减少后续维护成本
最易被忽略的是 NLS 参数:EF Core 8 默认按 NLS_DATE_FORMAT='DD-MON-RR' 发送 DateTime,而很多 Oracle 库设为 'YYYY-MM-DD HH24:MI:SS',导致 WHERE 条件隐式转类型、索引失效。上线前务必用 LogTo 捕获生成 SQL,检查有没有满屏 TO_DATE(...)。











