ppi*_*icz 161 c# sql-server dapper
如何对数据库执行插入并使用Dapper返回插入的标识?
我尝试过这样的事情:
string sql = "DECLARE @ID int; " +
"INSERT INTO [MyTable] ([Stuff]) VALUES (@Stuff); " +
"SELECT @ID = SCOPE_IDENTITY()";
var id = connection.Query<int>(sql, new { Stuff = mystuff}).First();
Run Code Online (Sandbox Code Playgroud)
但它没有用.
@Marc Gravell谢谢你的回复.我已经尝试过你的解决方案但是,下面仍有相同的异常跟踪
System.InvalidCastException: Specified cast is not valid
at Dapper.SqlMapper.<QueryInternal>d__a`1.MoveNext() in (snip)\Dapper\SqlMapper.cs:line 610
at System.Collections.Generic.List`1..ctor(IEnumerable`1 collection)
at System.Linq.Enumerable.ToList[TSource](IEnumerable`1 source)
at Dapper.SqlMapper.Query[T](IDbConnection cnn, String sql, Object param, IDbTransaction transaction, Boolean buffered, Nullable`1 commandTimeout, Nullable`1 commandType) in (snip)\Dapper\SqlMapper.cs:line 538
at Dapper.SqlMapper.Query[T](IDbConnection cnn, String sql, Object param) in (snip)\Dapper\SqlMapper.cs:line 456
Run Code Online (Sandbox Code Playgroud)
Mar*_*ell 267
如果使用它确实支持输入/输出参数(包括RETURN
值)DynamicParameters
,但在这种情况下,更简单的选项就是:
string sql = @"
INSERT INTO [MyTable] ([Stuff]) VALUES (@Stuff);
SELECT CAST(SCOPE_IDENTITY() as int)";
var id = connection.Query<int>(sql, new { Stuff = mystuff}).Single();
Run Code Online (Sandbox Code Playgroud)
jww*_*jww 49
KB:2019779,"使用SCOPE_IDENTITY()和@@ IDENTITY时可能会收到不正确的值",OUTPUT子句是最安全的机制:
string sql = @"
DECLARE @InsertedRows AS TABLE (Id int);
INSERT INTO [MyTable] ([Stuff]) OUTPUT Inserted.Id INTO @InsertedRows
VALUES (@Stuff);
SELECT Id FROM @InsertedRows";
var id = connection.Query<int>(sql, new { Stuff = mystuff}).Single();
Run Code Online (Sandbox Code Playgroud)
Tad*_*rić 38
一个迟到的答案,但这里是我们最终使用的答案的替代方案SCOPE_IDENTITY()
:OUTPUT INSERTED
仅返回插入对象的ID:
它允许您获取插入行的全部或部分属性:
string insertUserSql = @"INSERT INTO dbo.[User](Username, Phone, Email)
OUTPUT INSERTED.[Id]
VALUES(@Username, @Phone, @Email);";
int newUserId = conn.QuerySingle<int>(insertUserSql,
new
{
Username = "lorem ipsum",
Phone = "555-123",
Email = "lorem ipsum"
}, tran);
Run Code Online (Sandbox Code Playgroud)
返回带ID的插入对象:
如果你想你能得到Phone
和Email
甚至整个插排:
string insertUserSql = @"INSERT INTO dbo.[User](Username, Phone, Email)
OUTPUT INSERTED.*
VALUES(@Username, @Phone, @Email);";
User newUser = conn.QuerySingle<User>(insertUserSql,
new
{
Username = "lorem ipsum",
Phone = "555-123",
Email = "lorem ipsum"
}, tran);
Run Code Online (Sandbox Code Playgroud)
此外,使用此功能,您可以返回已删除或更新的行的数据.如果您使用触发器,请小心,因为:
从OUTPUT返回的列反映了INSERT,UPDATE或DELETE语句完成之后但在执行触发器之前的数据.
对于INSTEAD OF触发器,生成的返回结果就像INSERT,UPDATE或DELETE实际发生一样,即使触发操作没有发生任何修改也是如此.如果在触发器主体内部使用包含OUTPUT子句的语句,则必须使用表别名来引用触发器插入和删除的表,以避免使用与OUTPUT关联的INSERTED和DELETED表重复列引用.
更多关于它的文档:链接
您获得的InvalidCastException是由于SCOPE_IDENTITY是十进制(38,0).
您可以通过如下方式将其作为int返回:
string sql = @"
INSERT INTO [MyTable] ([Stuff]) VALUES (@Stuff);
SELECT CAST(SCOPE_IDENTITY() AS INT)";
int id = connection.Query<int>(sql, new { Stuff = mystuff}).Single();
Run Code Online (Sandbox Code Playgroud)
归档时间: |
|
查看次数: |
86152 次 |
最近记录: |