【问题标题】:Why is Dapper unable to return multiple inserted row ids?为什么 Dapper 无法返回多个插入的行 ID?
【发布时间】:2016-10-05 22:38:05
【问题描述】:

我有一个 SQL Server 表,其中插入了行:

var sql = @"
DECLARE @InsertedRows AS TABLE (Id BIGINT);
INSERT INTO Person ([Name], [Age]) OUTPUT Inserted.Id INTO @InsertedRows
VALUES (@Name, @Age);
SELECT Id FROM @InsertedRows;";

Person person = ...;

var id = connection.Query<long>(sql, person).First();

这一切都很好,但是如果我尝试插入多个项目并使用以下方法返回所有插入的 id:

IEnumerable<Person> people = ...;    
var ids = connection.Query<long>(sql, people);

我收到一个错误:

System.InvalidOperationException : 在此上下文中不允许使用可枚举的参数序列(数组、列表等)
在 Dapper.SqlMapper.GetCacheInfo(Identity identity, Object exampleParameters, Boolean addToCache)
在 Dapper.SqlMapper.d__23`1.MoveNext()
--- 从之前抛出异常的位置结束堆栈跟踪 ---

如何在 Dapper 中返回多个插入的 id?

【问题讨论】:

  • Query&lt;T&gt; 确实返回IEnumerable&lt;T&gt;,因此在第一个查询中使用First()
  • 问题不在于 Dapper 是否支持返回多个行 ID,而实际上是“插入后如何获取多个行 ID?”。它只是执行你给它的 SQL。您希望INSERT SQL 执行多次(取决于people),但最终选择执行一次。这将要求 Dapper 了解您正在执行的 SQL,但它没有。想想如果没有 Dapper(只是在普通 SQL 中)你将如何做到这一点,你会发现你正在尝试做的事情并不完全有意义——你需要多个插入语句
  • 实际上这不是真的,dapper 知道如何将 IEnumerable 映射到转义的 SQL,因此将其与使用普通 SQL 执行此操作的方式进行比较是无关紧要的。您可以自己尝试一下,将sql 替换为:INSERT INTO Person ([Name], [Age]) VALUES (@Name, @Age); 并用SqlMapper.Execute() 执行它,您将看到正确插入的所有项目。
  • @Rob,我明白你现在的意思了。嗯...我希望它以以下方式运行查询:DECLARE @InsertedRows AS TABLE (Id BIGINT); INSERT INTO Person ([Name], [Age]) OUTPUT Inserted.Id INTO @InsertedRows VALUES (@Name1, @Age1),(@Name2, @Age2),...; SELECT Id FROM @InsertedRows;"; 确实可以使用纯 SQL。在那种情况下,如何在 Dapper 中实现相同的目标?
  • @MaYaN 我相信最好的方法是进行单独的查询: 1. 创建一个临时表(而不仅仅是一个变量)。以Execute 而不是Query 的身份运行插入,并输出到临时表中。对临时表运行Query,然后删除临时表。对我来说,这似乎并不理想,但我正在努力寻找更好的方法。

标签: c# .net sql-server dapper


【解决方案1】:

某处某处需要循环。您有一个插入一行的 sql 语句,并在列表中发送代码。由于您喜欢字符串文字中的 SQL,因此我会坚持一次插入一个人,将循环放入 C# 并使用 SELECT SCOPE_IDENTITY() 恢复 C# 中的每个 id。您不再需要 @InsertedRows 或 OUTPUT。

如果您真的想在 SQL 中循环,我相信您需要查看表值参数以传递插入列表。 Dapper 很高兴返回多个 Id。它抱怨多人作为输入参数。

有一天,希望很快,我们将回顾一下字符串文字中的 SQL,就像我们现在看到 goat sacrifice 一样。

【讨论】:

  • INSERT Production.[TestScrapReason] (Name) OUTPUT INSERTED.ScrapReasonID, INSERTED.Name, INSERTED.ModifiedDate SELECT [Name] FROM [AdventureWorks2012].[Production].[ScrapReason]有效?
猜你喜欢
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 2012-08-14
  • 2012-09-12
  • 2022-11-25
  • 2012-01-06
相关资源
最近更新 更多