I have a SQL Server table into which rows are inserted using:
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();
This all works well however if I try to insert multiple items and return all the inserted ids using:
IEnumerable<Person> people = ...; var ids = connection.Query<long>(sql, people);
I get an error:
System.InvalidOperationException : An enumerable sequence of parameters (arrays, lists, etc) is not allowed in this context
at Dapper.SqlMapper.GetCacheInfo(Identity identity, Object exampleParameters, Boolean addToCache)
--- End of stack trace from previous location where exception was thrown ---
How would one return multiple inserted ids in Dapper?
Something, somewhere, needs to loop. You have a sql statement that inserts one row, and code sending in a list. Since you like your SQL in string literals, I would stick to inserting one person at a time, putting the loop in the C# and recovering each id in the C# using
SELECT SCOPE_IDENTITY(). You no longer need @InsertedRows, or OUTPUT.
If you really want to loop in SQL, I believe you'll need to look at table valued parameters for passing your list of inserts. Dapper is very happy to return multiple Ids. It's complaining about multiple people as an input parameter.
One day, hopefully soon, we're going to look back at SQL in string literals like we presently look at goat sacrifice.