使用dapper.net返回mysql LAST_INSERT_ID()时无效的强制转换

时间:2011-12-12 16:24:03

标签: c# mysql dapper

此问题已在MSSQL中提及:

How do I perform an insert and return inserted identity with Dapper?

但是这个解决方案不适用于mysql。

要使用mysql将LAST_INSERT_ID()强制转换为整数,您必须这样做:

SELECT CAST(LAST_INSERT_ID() AS UNSIGNED INTEGER);

堆栈跟踪是:

Dapper.<QueryInternal>d__13`1.MoveNext() in sqlMapper.cs:607
   System.Collections.Generic.List`1..ctor(IEnumerable`1 collection) +159
   System.Linq.Enumerable.ToList(IEnumerable`1 source) +36
   Dapper.SqlMapper.Query(IDbConnection cnn, String sql, Object param, IDbTransaction transaction, Boolean buffered, Nullable`1 commandTimeout, Nullable`1 commandType) in sqlMapper.cs:535

有没有人在MySQL中解决过这个问题?

修改

我已成功完成以下工作:

var id = connection.Query<ulong>("SELECT CAST(LAST_INSERT_ID() AS UNSIGNED INTEGER);").Single();

也许不理想,但它有效。

3 个答案:

答案 0 :(得分:16)

我会把这个留在这里作为其他任何可能搜索此问题的人的答案。

我已成功完成以下工作:

var id = connection.Query<ulong>("SELECT CAST(LAST_INSERT_ID() AS UNSIGNED INTEGER);").Single();

也许不理想,但它有效。

答案 1 :(得分:8)

我实际上可以对此有所了解,因为我花了最后一小时才想知道为什么我的SELECT LAST_INSERT_ID()查询在一台MySQL服务器上运行而不是另一台运行。一台服务器运行MySQL 5.5.11(生产),另一台运行5.5.31(本地开发)。

在版本5.1.67,5.5.29和5.6.9之前(在每个版本中)LAST_INSERT_ID()用于返回有符号整数。

现在LAST_INSERT_ID()会返回一个未签名的BIGINT,这意味着我的5.5.31服务器上运行的代码有效:

var id = cn.Query<ulong>("SELECT LAST_INSERT_ID();").First();

...但是对旧的5.5.11服务器执行时会被破坏。

这里记录了:

  

http://dev.mysql.com/doc/refman/5.5/en/information-functions.html#function_last-insert-id

     

从MySQL 5.5.29开始,该值的类型为BIGINT UNSIGNEDBIGINT(已签名)之前。

我最初的解决方案是将LAST_INSERT_ID()的结果转换为无符号BIGINT,以使代码在这两个服务器版本中都可移植,但是(惊讶,惊讶)MySQL团队添加了障碍。

您无法使用CAST() functionLAST_INSERT_ID()直接投射到未签名(或甚至签名)BIGINT,因为它不受支持。您可以投射到的唯一整数类型是SIGNED INTEGERUNSIGNED INTEGER。这是一种痛苦,因为如果出于某种原因你真的需要一个自动递增BIGINT id,它增加超过4294967295,那么无符号整数将不会是一个足够大的类型来强制转换。

答案 2 :(得分:1)

使用Convert.ToInt64(value)解决了它。