我正在使用
Dapper从ASP.NET MVC 3(.NET 4.0)应用程序对sql Server 2008 R2 Express实例执行以下查询.
INSERT INTO Customers ( Type,Name,Address,ContactName,ContactNumber,ContactEmail,Supplier) VALUES ( @Type,@Name,@Address,@ContactName,@ContactNumber,@ContactEmail,@Supplier) SELECT @@IDENTITY
对connection.Query< int>(sql,…)的调用抛出了无效的强制转换异常.我调试了它,它是在Dapper在返回的sqlDataReader上调用GetValue的时候.
返回类型GetValue
是Object,在调试器show中检查它是一个盒装小数.
如果我将select更改为SELECT CAST(@@ IDENTITY as int),则GetValue的返回值为Boxed int,并且不会抛出异常.
Id列绝对是int类型;为什么SELECT @@ IDENTITY会返回小数?
一些其他信息:
>数据库是全新的.
> Customers表是我添加到它的唯一对象.数据库中没有其他(用户)表,视图,触发器或存储过程.
>数据库中有10行,其中Id是1,2,3,4,5,6,7,8,9,10(即列不超出int的限制).
我的表定义是
CREATE TABLE [dbo].[Customers]( [Id] [int] IDENTITY(1,1) NOT NULL,[Type] [int] NOT NULL,[Name] [nvarchar](255) NOT NULL,[Address] [nvarchar](1000) NOT NULL,[ContactName] [nvarchar](255) NOT NULL,[ContactNumber] [nvarchar](50) NOT NULL,[ContactEmail] [nvarchar](255) NOT NULL,[Supplier] [nvarchar](255) NOT NULL,CONSTRAINT [PK_Customers] PRIMARY KEY CLUSTERED ( [Id] ASC )WITH ( PAD_INDEX = OFF,STATISTICS_NORECOMPUTE = OFF,IGNORE_DUP_KEY = OFF,ALLOW_ROW_LOCKS = ON,ALLOW_PAGE_LOCKS = ON) ON [PRIMARY] ) ON [PRIMARY]
解决方法
>
@@identity returns a numeric(38,0).您需要将其转换为int.
SELECT CAST(@@ identity AS INT)
>另外,请尝试使用scope_identity.如果Customers表上有任何触发器,您最终可能会从另一个表中获取最后一个标识.
>最后,由于您使用的是dapper,因此您需要将所有内容包装在存储过程中,以便保证在同一批次中执行插入然后选择标识.
从理论上讲,它应该大部分时间都可以自己执行这两个任务.但是如果你不得不两次去数据库就会出现问题. (例如,这如何与连接池一起工作?如何丢弃连接?等等)如果你只是将它全部存放在存储过程中,你将不必担心在路上需要额外的努力.