现在唯一推荐的驱动是oracle.manageddataaccess,它纯托管、跨平台、无需安装oracle客户端;system.data.oracleclient早已过时且不支持.net core/5+。

Oracle.ManagedDataAccess 是现在唯一推荐的驱动
用 System.Data.OracleClient?别试了,它早在 .NET Framework 4.0 就被标记为过时,.NET Core / .NET 5+ 完全不支持。现在唯一靠谱、官方维护、跨平台(Windows/macOS/Linux)的选择是 Oracle.ManagedDataAccess —— 纯托管实现,不用装 Oracle 客户端,也不依赖 ORACLE_HOME。
安装方式很简单:dotnet add package Oracle.ManagedDataAccess。如果是旧项目还在用 System.Data.OracleClient,直接删引用、换 NuGet 包、改命名空间(using Oracle.ManagedDataAccess.Client;),否则运行时必报 TypeLoadException 或 Could not load file or assembly。
连接字符串里最容易写错的三个地方
Oracle 连接字符串格式比 SQL Server 更敏感,稍有空格或大小写不对就抛 OracleException: ORA-12154: TNS could not resolve the connect identifier。
-
Data Source不要硬写(DESCRIPTION=...)长串——除非你真需要定制网络参数;优先用 Easy Connect 格式:Data Source=localhost:1521/XE(XE 是服务名,不是 SID) - 服务名(Service Name)和 SID 不一样:12c+ 默认用服务名,查数据库用
SELECT value FROM v$parameter WHERE name = 'service_names';,别凭印象填ORCL - 用户名密码区分大小写,且默认 Oracle 12c+ 账户是大写(如
SYSTEM),如果用小写登录会提示ORA-01017: invalid username/password,哪怕密码对
用 OracleConnection + OracleCommand 读写必须配对使用 using
Oracle 的连接资源释放比 SQL Server 更“娇气”,不显式释放容易快速耗尽连接池(尤其在 Web 应用里),表现为后续连接卡住、超时、或报 ORA-12519: no appropriate service handler。
正确姿势是每个 OracleConnection 和 OracleCommand 都套 using:
using (var conn = new OracleConnection(connStr))
{
conn.Open();
using (var cmd = conn.CreateCommand())
{
cmd.CommandText = "SELECT COUNT(*) FROM users WHERE status = :p1";
cmd.Parameters.Add(new OracleParameter("p1", "active"));
var count = (int)cmd.ExecuteScalar();
}
}
注意:OracleParameter 的名字带冒号(:p1)是合法的,但实际传参时 Add 方法里不要带冒号——写成 "p1",否则会报 ORA-01036: illegal variable name/number。
批量插入用 OracleBulkCopy,别用循环 INSERT
100 条记录用循环 ExecuteNonQuery 插入,在 Oracle 上可能比 SQL Server 慢 5–10 倍——因为每次都要走完整网络往返 + 解析 + 执行计划生成。
真正该用的类是 OracleBulkCopy(在 Oracle.ManagedDataAccess.Client 命名空间下),但它要求目标表字段顺序、类型、甚至空值约束都严格匹配 DataTable 列,否则直接抛异常:
- 确保
DataTable列名和目标表列名**完全一致(大小写敏感)** - 日期列不能为
null,除非目标表字段允许 NULL;否则报ORA-01843: not a valid month(其实是隐式转换失败) - 主键或唯一约束冲突不会自动跳过,会中断整个批次;想忽略重复,得先用
MERGE语句替代
简单场景下,它比 100 次单条 INSERT 快一个数量级;复杂业务逻辑则老实用 INSERT ALL 或分批 ExecuteNonQuery。
Oracle 的连接行为和错误反馈很“直球”——它不帮你猜意图,错一个字符、少一个分号、大小写不对,就给你个含糊的 ORA 错误码。调试时别只盯着 C# 代码,顺手连上 SQL*Plus 或 SQL Developer,用同样的用户名密码和服务名试试能不能登进去,这一步省掉一半排查时间。











