MSSQL中用Dapper无法更新decimal字段,SSMS执行正常
遇到这种情况真的挺让人困惑的——明明在SSMS里能正常更新,到了Dapper里就有字段没反应,我之前也踩过类似的坑,咱们一步步来排查:
最可能的原因:SQL语句不完整或有笔误
看你提供的C#代码片段里,SQL语句写到WHERE test_temp.product_id_part_1 = 10877 AND test_te...就截断了,这大概率是问题所在!可能实际代码里的WHERE子句没写完(比如漏掉了mp.product_id_part_2 = 0),或者拼写错误,导致Dapper执行时根本没匹配到要更新的行,自然aut_z3字段没变化。
排查方法:把C#中生成的完整SQL语句打印出来(比如用Debug.WriteLine(sqlStatement)),和SSMS里能正常执行的版本逐字对比,确保完全一致。
检查受影响行数,确认是否命中目标行
不管SQL看起来对不对,先确认Dapper执行后到底有没有行被更新。修改代码,获取Execute方法的返回值:
using(var connection = new SqlConnection("你的连接字符串")) { var sqlStatement = @"UPDATE test_temp SET aut_z3 = 2.99, slo_z3 = 0, ita_z3 = 0 WHERE product_id_part_1 = 10877 AND product_id_part_2 = 0"; int rowsAffected = connection.Execute(sqlStatement); Console.WriteLine($"受影响行数:{rowsAffected}"); }
- 如果返回
0:说明WHERE条件没匹配到任何行,要么是SQL条件写错了,要么是数据库里对应的数据不存在。 - 如果返回大于
0:说明行被命中了,但aut_z3没更新,那就要看字段本身的问题。
字段类型不匹配或Dapper的参数转换问题
如果你的代码实际是用参数传递值(而不是硬写2.99),比如:
var param = new { autZ3 = 2.99, sloZ3 = 0, itaZ3 = 0, part1 = 10877, part2 = 0 }; var sql = @"UPDATE test_temp SET aut_z3 = @autZ3, slo_z3 = @sloZ3, ita_z3 = @itaZ3 WHERE product_id_part_1 = @part1 AND product_id_part_2 = @part2";
那要检查数据库中aut_z3的字段类型:比如如果是decimal(18,2),而你传的是double类型的2.99,Dapper可能在转换时出现精度丢失?这种情况可以试试在代码里用decimal类型传值:autZ3 = 2.99m。
事务未提交导致更新未生效
如果你的代码是在事务中执行的,比如用了TransactionScope或者DbTransaction,但最后没有提交事务,那更新操作会被回滚,自然看不到效果。检查代码里是否有类似这样的逻辑:
using(var scope = new TransactionScope()) { connection.Execute(sqlStatement); // 这里漏掉了 scope.Complete(); }
如果是这种情况,加上scope.Complete()或者transaction.Commit()即可。
简化SQL,排除干扰
如果上面的方法都没找到问题,试试简化SQL语句,只更新aut_z3字段,看是否生效:
var sql = @"UPDATE test_temp SET aut_z3 = 2.99 WHERE product_id_part_1 = 10877 AND product_id_part_2 = 0"; int rows = connection.Execute(sql);
如果这样aut_z3能正常更新,那说明之前的SQL里其他字段的更新可能有冲突?不过这种情况比较少见,但可以用来缩小排查范围。
内容的提问来源于stack exchange,提问作者Tadej

