【DM版本】:
DM Database Server 64 V8
DB Version: 0x7000d
03134284404-20250930-295335-20164
Msg Version: 49
Gsu level(5) cnt: 0
兼容性标识: MySql(4)
【操作系统】:Windows 11
【CPU】: x64
【问题描述】*:
达梦驱动和新版数据库存在兼容性问题, 表现为MySQL兼容模式下, 对带有自增主键的表插入数据后, EF驱动会产生数据没有写入成功的报错
Database operation expected to affect 1 row(s) but actually affected 0 row(s)
排查具体情况时确认Add操作会生成如下sql语句
INSERT INTO "archives_box" ("bind_time", "box_name", "box_no", "epc", "has_rfid", "last_check_time", "tid")
VALUES (:p0, :p1, :p2, :p3, :p4, :p5, :p6);
SELECT "lsh"
FROM "archives_box"
WHERE sql%ROWCOUNT = 1 AND "lsh" = scope_identity();
其中发现问题出在达梦EF驱动会在插入具有自增主键的数据后, INSERT语句后额外添加如下的语句存在问题
SELECT "lsh"
FROM "archives_box"
WHERE sql%ROWCOUNT = 1 AND "lsh" = scope_identity();
从语义上看,这条查询语句以试图查询获取上面INSERT语句新增项的自增主键值
但在达梦数据库管理工具中测试这个语句的时候发现, INSERT执行成功, 但下面的查询实际返回了0行结果, 由于在EFCore中该语句执行失败抛出异常后数据库实际无写入数据, 应该是进行了事务回滚
更具体的是: 局部变量sql%ROWCOUNT和函数scope_identity()在执行时实际返回了null. 该问题出现在新版达梦数据库服务上, 但旧版本未出现此问题.
看是不是因为达梦版本更新导致该语句行为异常或已不再兼容原来旧版本的达梦EF驱动.
额外补充信息:
sql%ROWCOUNT是ORACLE数据库独有的DDL语句影响行数,对应MySql在的是ROW_COUNT(),但测试确认达梦数据库不支持该方法。
scope_identity()是SQL SERVER独有的标识ID获取函数,对应MySql的等效函数是LAST_INSERT_ID(),且测试确认该函数在查询时实际可返回数据。尚不清楚是不是EF驱动需要修改什么配置来改变生成SQL时使用的函数名称。
补充2: 达梦EF驱动的程序集中未检索到LAST_INSERT_ID()的字符串, 仅发现了在生成代码新增语句追加自增标识的方法Microsoft.EntityFrameworkCore.Dm.Update.Internal.DmUpdateSqlGenerator.AppendIdentityWhereCondition(System.Text.StringBuilder,Microsoft.EntityFrameworkCore.Update.ColumnModification)中在构造SQL语句时写入了scope_identity(),也就是说达梦的3.1版的EF驱动尚未支持目前最新版本达梦数据库引擎的这个函数行为变更。
补充3:将查询语句修改为如下样式可正确返回预期数据
SELECT "lsh"
FROM "archives_box"
WHERE "lsh" = last_insert_id() limit 0,1;
