Как выполнить вставку в базу данных и вернуть вставленную идентификацию с помощью 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();
Но это не сработало.
@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
c#
sql-server
dapper
ppiotrowicz
источник
источник
numeric
, а? Возможно, использовать свой оригинальный код иselect @id
? (это просто добавляет актерский состав). Я сделаю примечание, чтобы убедиться, что это работает автоматически в будущих сборках dapper. Еще один вариант на данный моментselect cast(SCOPE_IDENTITY() as int)
- опять же немного некрасиво. Я исправлю это.scope_identity
возвращаемый тип естьnumeric(38,0)
. +1 действительно хорошая находка. Никогда, хотя на самом деле, и я уверен, что я не единственный.Query<foo>
что вставляет значения, а затем выбирает *, где id = SCOPE_IDENTITY ().Query
.Query
и получать первое значение из возвращенной коллекции, я думаю,ExecuteScalar<T>
в этом случае имеет больше смысла, поскольку обычно возвращается не более одного значения.KB: 2019779 , «Вы можете получить неправильные значения при использовании SCOPE_IDENTITY () и @@ IDENTITY», предложение OUTPUT - самый безопасный механизм:
источник
An enumerable sequence of parameters (arrays, lists, etc) is not allowed in this context
Поздний ответ, но здесь является альтернативой к
SCOPE_IDENTITY()
ответам , которые мы заканчивали с помощью: OUTPUT вставленногоВозврат только идентификатора вставленного объекта:
Это позволяет вам получить все или некоторые атрибуты вставленной строки:
Вернуть вставленный объект с идентификатором:
Если вы хотите, вы можете получить
Phone
иEmail
даже целый вставленный ряд:Также с этим вы можете вернуть данные удаленных или обновленных строк. Просто будьте осторожны, если вы используете триггеры, потому что (по ссылке, упомянутой ранее):
Подробнее об этом в документации: ссылка
источник
Исключение InvalidCastException, которое вы получаете, связано с тем, что SCOPE_IDENTITY является десятичным числом (38,0) .
Вы можете вернуть его как int, приведя его следующим образом:
источник
Не уверен, что это потому, что я работаю против SQL 2000 или нет, но мне пришлось сделать это, чтобы заставить его работать.
источник
select cast(SCOPE_IDENTITY() as int)
?Есть отличная библиотека, которая сделает вашу жизнь проще. Dapper.Contrib.Extensions. После включения этого вы можете просто написать:
источник
Если вы используете Dapper.SimpleSave:
источник