解决 Dapper.Contrib 报错“值对于 Int32 太大或太小”问题
需求:在使用 Dapper.Contrib 执行 Insert 方法的时候,插入单条数据对于自增主键字段的返回值为插入后的值,当返回值大于 2147483647 的时候,Dapper.Contrib 会抛出异常“值对于 Int32 太大或太小”问题。
使用 Dapper.Contrib 插入数据的时候,报错“值对于 Int32 太大或太小”,此时数据库已经插入成功!怀疑是 ORM 框架的问题,然后在 GitHub 上面搜索,发现是一个已知的问题,Dapper 团队因为担心影响太大,一直没有修复,也有其他作者给 Dapper 提供 pr,也被关闭了,如下图:
https://github.com/DapperLib/Dapper.Contrib/issues/4
异常原因是获取到自增值后,以 Sql Server 适配器为例,强制转换成 int 类型报错,int 最大值为(int.MaxValue):2147483647,如下图:
复现方法,新建一个表,自增主键从 2147483648 开始,SQL 脚本如下:
- CREATE TABLE Test
- (
- Id BIGINT IDENTITY(2147483648,1) PRIMARY KEY,
- Name NVARCHAR(255)
- );
引用 Dapper.Contrib 包,执行插入操作,代码如下:
- using Dapper.Contrib.Extensions;
- using System;
- using System.Data.SqlClient;
- namespace ConsoleApp2
- {
- internal class Program
- {
- const string sqlConn = "Data Source=.;Initial Catalog=TestDB1;user id=sa;password=123456";
- static void Main(string[] args)
- {
- try
- {
- using (var connection = new SqlConnection(sqlConn))
- {
- var result = connection.Insert(new User { Name = "value" });
- Console.WriteLine(result);
- }
- }
- catch (Exception ex)
- {
- Console.WriteLine(ex);
- }
- Console.WriteLine("ok");
- Console.ReadKey();
- }
- }
- [Table("Test")]
- public class User
- {
- [Key]
- public long Id { get; set; }
- public string Name { get; set; }
- }
- }
报错如下:
解决方案
将 Dapper.Contrib 替换成 Dapper.Contrib.Unofficial 包,命令如下:
- NuGet\Uninstall-Package Dapper.Contrib
- NuGet\Install-Package Dapper.Contrib.Unofficial -Version 2.0.97
测试不再报错,如下图:
提示:Dapper.Contrib.Unofficial 没有经过完整测试,请自行测试后使用!
修改后的代码 GitHub 地址:https://github.com/itsvse/Dapper.Contrib
(完)