Oracle连接字符串需添加ENABLE RDBMS=TRUE以支持自增列,Dapper Plus批量操作须手动映射序列名且大小写敏感,BulkUpdate需显式指定匹配键避免NULL导致WHERE失效,事务中应避免Bulk与普通Execute混用以防死锁。
Oracle连接字符串里必须启用自增列支持
dapper plus 对 oracle 的批量操作(如 insert、update)默认不处理序列(sequence)+ 触发器(trigger)模拟的自增主键。如果你的表主键靠 before insert 触发器从 seq_table_id.nextval 赋值,dapper plus 会因读不到返回值而报 ora-01008: not all variables bound 或插入后 id 为 0。
解决方法是在连接字符串中显式开启 Oracle 自增识别:
DATA SOURCE=ORCL;USER ID=usr;PASSWORD=pwd;ENABLE RDBMS=TRUE;
注意:ENABLE RDBMS=TRUE 是 Oracle Data Provider for .NET(ODP.NET)的专有参数,不是所有驱动都支持。若用的是 Oracle.ManagedDataAccess(推荐),该参数有效;若用 System.Data.OracleClient(已弃用),此参数无效且会抛异常。
Dapper Plus BulkInsert 需手动映射 Sequence 名称
即使启用了 ENABLE RDBMS=TRUE,Dapper Plus 仍无法自动推断 Oracle 序列名。它默认尝试查 SELECT SEQUENCE_NAME FROM USER_SEQUENCES WHERE SEQUENCE_NAME = 'TABLENAME_SEQ',但实际命名往往不匹配(比如叫 SEQ_USER_ID 而非 USER_SEQ)。
必须在插入前用 EntityMapping 显式绑定:
var mapper = DapperPlusManager.Entity<User>();
mapper.Table("USERS");
mapper.Identity(x => x.Id, "SEQ_USER_ID"); // 关键:指定序列名
常见疏漏点:
- 序列名大小写敏感(Oracle 默认大写),传
"seq_user_id"会查不到 -
Identity()必须在首次调用BulkInsert()前注册,运行时修改无效 - 若表无触发器,仅靠序列 + 手动
INSERT INTO ... VALUES (SEQ_USER_ID.NEXTVAL, ...),则 Dapper Plus 不适用,应改用原生 Dapper +RETURNING子句
BulkUpdate 不支持 WHERE 条件含 NULL 值
Oracle 的 UPDATE ... WHERE COL = :val 在 :val 为 NULL 时逻辑恒假(SQL 标准),而 Dapper Plus 的 BulkUpdate 默认把实体所有非空字段当更新目标,并用全部属性做 WHERE 匹配 —— 若实体中某个 WHERE 字段是 null(比如 user.Status == null),生成的 SQL 就变成 WHERE STATUS = NULL,永远不生效。
正确做法是显式指定键字段和更新字段:
connection.BulkUpdate(users,
bulk => bulk
.MatchKey(x => x.Id) // 只用 Id 当 WHERE 条件
.Map(x => x.Name).ToColumn("NAME")
.Map(x => x.Email).ToColumn("EMAIL"));
否则容易出现“执行成功但数据库没变化”的静默失败。
事务内混合使用 Bulk 和普通 Execute 可能死锁
Oracle 在同一事务中交替执行批量 DML(如 BulkInsert)和单条 Execute(如日志插入),可能因锁粒度差异引发死锁,错误信息类似:
ORA-00060: deadlock detected while waiting for resource
根本原因是 Dapper Plus 的批量操作底层调用 ArrayBinding(数组绑定),会一次性请求多行锁;而普通 Execute 是逐行执行,锁释放时机不同。
规避方式:
- 把所有批量操作集中放在事务开头或结尾,避免穿插
- 确认
OracleCommand.ArrayBindCount设置合理(Dapper Plus 默认 1000,过高易占满 PGA 内存) - 若必须混合,对普通
Execute操作加SELECT ... FOR UPDATE NOWAIT预检锁状态
Oracle 的批量行为和 SQL Server 差异很大,别套用 MSSQL 经验去调参。


















