ora-28040错误首要原因是客户端与数据库认证协议不匹配,须在服务端sqlnet.ora中配置sqlnet.allowed_logon_version_server(如设为12a)并重启监听器;jdbc thin不读该文件,.net core需升级instant client至23c匹配版本。

ORA-28040:客户端协议不匹配是首要原因
Oracle 23c 默认禁用旧版身份验证协议(如 SEC_PROTOCOL_ERROR),而低版本 Oracle 客户端(如 Instant Client 19c 或更早)默认不支持 ora_authentication_protocol=sha512。现象是:SQL*Plus、JDBC Thin 能连,但 .NET Core + EF Core 报 ORA-28040: No matching authentication protocol。
这不是连接字符串写错了,而是握手阶段协议协商失败——服务端拒绝了客户端的认证请求。
- 必须升级 Oracle 客户端到
instantclient-basic-windows.x64-23.5.0.0.0dbru.zip或更高版本(与 23c 主版本严格对齐) - 临时方案(仅限开发环境):在数据库服务器的
$ORACLE_HOME/network/admin/sqlnet.ora中添加SQLNET.ALLOWED_LOGON_VERSION_SERVER=12a,但生产环境禁用 - EF Core 连接时无法绕过该协议校验,
Oracle.ManagedDataAccess.Core会原样传递协议能力,不提供降级开关
连接字符串里用 tns 别名直接报 ORA-12154
.NET Core 的托管驱动(Oracle.ManagedDataAccess.Core)默认不加载 tnsnames.ora,哪怕你设置了 TNS_ADMIN 环境变量也无效。它不会去解析别名,而是把 Data Source=ORCLPDB 当作主机名直连,自然失败。
解决方式不是“配对文件”,而是放弃别名,改用完整格式:
- 优先用 Easy Connect:
Data Source=localhost:1521/ORCLPDB1(注意是SERVICE_NAME,不是 SID) - 或硬编码 DESCRIPTION:
Data Source=(DESCRIPTION=(ADDRESS=(PROTOCOL=TCP)(HOST=localhost)(PORT=1521))(CONNECT_DATA=(SERVICE_NAME=ORCLPDB1))) - 若从
appsettings.json读取,务必对值调用.Trim(),Windows 编辑器常带 BOM 或尾部空格,导致解析失败
EF Core 迁移执行时报 ORA-01031 或静默失败
Update-Database 失败,表面看是连接问题,实际多因权限缺失。Oracle 不像 SQL Server 那样区分“连接成功”和“无 DDL 权限”,它统一返回 ORA-01031: insufficient privileges 或伪装成连接超时。
关键检查点:
- 数据库用户必须显式授予:
GRANT CREATE TABLE, ALTER ANY TABLE, DROP ANY TABLE, CREATE SEQUENCE TO myuser; -
Oracle.EntityFrameworkCore和Oracle.ManagedDataAccess.Core版本必须完全一致(如都用8.0.0),混用会导致UseOracle()初始化失败且无提示 - 连接字符串中不能含中文、全角符号或多余空格;
Password含@、/、:时,必须用英文双引号包裹:Password="Pass@123"
实体生成或查询时字段映射异常
Oracle 默认将未加引号的标识符转为大写,而 EF Core 模型属性名是小写,导致列找不到。例如表 PEOPLE 有列 ID,但模型写 public int id { get; set; },EF 尝试查 id(小写),Oracle 返回空。
这不是 ORM bug,是大小写语义差异:
- 必须用
[Column("ID")]显式标注所有列名 - 表名同理:
[Table("PEOPLE")],否则 EF 默认按类名小写查people - 自定义 SQL 查询中,参数占位符用冒号
:paramName,不是 SQL Server 的@paramName;结尾不能带分号,否则报ORA-00933
真正卡住人的地方,往往不是语法错,而是协议层、TNS 解析层、权限层这三处隐性断点同时存在。一个 ORA-1017 可能由密码末尾空格 + SEC_CASE_SENSITIVE_LOGON=TRUE + PDB 上下文错位共同触发,得逐层排除,不能只盯连接字符串本身。











