推荐使用 Oracle.ManagedDataAccess(无 .Core 后缀),它纯托管、不依赖本地客户端,.NET Framework 项目严禁使用 .Core 版本,连接字符串优先采用 EZConnect 格式如 "User Id=u;Password=p;Data Source=localhost:1521/XEPDB1;",并用 using 确保连接及时释放。

用 Oracle.ManagedDataAccess 就能连,别碰 System.Data.OracleClient(已弃用)或 Oracle.DataAccess(需本地客户端),更别装错包名带 .Core 的——那是给 .NET Core / .NET 5+ 用的,.NET Framework 项目装了直接报 Could not load file or assembly。
装对 NuGet 包:只认 Oracle.ManagedDataAccess
Visual Studio 里右键项目 → “管理 NuGet 包” → 搜索 Oracle.ManagedDataAccess(无任何后缀),安装它。这个包纯托管、不依赖 Oracle 客户端安装,部署干净。
- 如果项目是 .NET Framework(如 4.7.2、4.8),绝对不要选
Oracle.ManagedDataAccess.Core—— 它在 .NET Framework 下根本加载不了 - 旧项目若还引用着
System.Data.OracleClient,得手动删掉引用并清理 using,否则编译可能过,运行时会静默失败或抛NotSupportedException - 装完检查输出目录:应该有
Oracle.ManagedDataAccess.dll,没别的 Oracle 相关 dll
连接字符串写法:优先用 Easy Connect,避开 tnsnames.ora
别手写 (DESCRIPTION=(ADDRESS=...)) 那种长串,除非你真要调网络参数;90% 场景用 Data Source=host:port/service_name 最稳。
- 示例:
"User Id=myuser;Password=mypass;Data Source=localhost:1521/XEPDB1;"—— 注意末尾分号和大小写:服务名XEPDB1是 Oracle 12c+ 默认 PDB 名,不是XE(那是 SID) - 查服务名:连上数据库执行
SELECT value FROM v$parameter WHERE name = 'service_names';,别靠记忆填ORCL或orcl - 密码含
@、/等字符?URL 编码太麻烦,建议改密码;或者换 Windows 身份验证(需 DBA 配置external_auth) - 连接字符串里 User Id 和 Password 前后不能有空格,否则
ORA-01017可能悄无声息地触发
OracleConnection.Open() 报 ORA-12154?先跑 tnsping
这个错误几乎从不表示网络不通,而是服务名解析失败。别急着改防火墙,先验证基础连通性。
- 命令行执行:
tnsping localhost:1521/XEPDB1(把你的服务名代进去)。如果它都返回OK,那Open()才有可能成功 - 监听器没启?Linux/macOS 上跑
lsnrctl status,Windows 上看服务列表里OracleOraDB21Home1TNSListener是否运行 - 如果
tnsping失败但端口通(telnet localhost 1521成功),说明监听器没配好服务名,不是你代码的问题 - 异常里的
ex.Number比消息更准:12154是服务名错,12541是监听器没响应,1017是账号密码错
读写数据时最常踩的三个坑
连接通了不等于能读写,参数、类型、资源释放三处最容易翻车。
-
OracleCommand.Parameters.Add()传参名别带冒号:cmd.Parameters.Add(new OracleParameter("p1", "active"))✅,写成":p1"❌,否则ORA-01036 - DateTime 字段读出来是
1900-01-01?大概率是字段为TIMESTAMP,但OracleCommand默认当DATE处理(只到秒)。显式指定类型:cmd.Parameters.Add("p_time", OracleDbType.TimeStamp).Value = DateTime.Now; - 连接不套
using?Web 应用里很快耗尽连接池,后续请求卡住或报ORA-12519。必须这样写:using (var conn = new OracleConnection(connStr)) { conn.Open(); using (var cmd = conn.CreateCommand()) { ... } }
服务名大小写、参数名漏冒号、连接不释放——这三个点看似小,但在真实项目里反复导致上线后偶发失败,比语法错误更难定位。


















