Comment effectuer une insertion dans la base de données et renvoyer l'identité insérée avec Dapper?
J'ai essayé quelque chose comme ça:
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();
Mais ça n'a pas marché.
@Marc Gravell merci, pour la réponse. J'ai essayé votre solution mais, toujours la même trace d'exception est ci-dessous
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
la source
la source
numeric
, hein? Peut-être utiliser votre code d'origine etselect @id
? (cela ajoute juste un casting). Je vais faire une note pour m'assurer que cela fonctionne automatiquement dans les futures versions dapper. Une autre option pour l'instant estselect cast(SCOPE_IDENTITY() as int)
- encore une fois, un peu moche. Je vais réparer ça.scope_identity
type de retour étaitnumeric(38,0)
. +1 une très bonne trouvaille. Jamais vraiment pensé et je suis sûr que je ne suis pas le seul.Query<foo>
que les valeurs insèrent puis sélectionne * où id = SCOPE_IDENTITY ().Query
.Query
et d'obtenir la première valeur de la collection retournée, je pense queExecuteScalar<T>
cela a plus de sens dans ce cas, car au plus une valeur est normalement retournée.KB: 2019779 , "Vous pouvez recevoir des valeurs incorrectes lors de l'utilisation de SCOPE_IDENTITY () et @@ IDENTITY", la clause OUTPUT est le mécanisme le plus sûr:
la source
An enumerable sequence of parameters (arrays, lists, etc) is not allowed in this context
Une réponse tardive, mais voici une alternative aux
SCOPE_IDENTITY()
réponses que nous avons fini par utiliser: OUTPUT INSERTEDRenvoie uniquement l'ID de l'objet inséré:
Il vous permet d'obtenir tout ou partie des attributs de la ligne insérée:
Renvoyer l'objet inséré avec l'ID:
Si vous le souhaitez, vous pouvez obtenir
Phone
etEmail
ou même toute la ligne insérée:De plus, vous pouvez renvoyer les données des lignes supprimées ou mises à jour . Faites juste attention si vous utilisez des déclencheurs car (à partir du lien mentionné précédemment):
Plus d'informations dans la documentation: lien
la source
L'exception InvalidCastException que vous obtenez est due au fait que SCOPE_IDENTITY est un décimal (38,0) .
Vous pouvez le renvoyer en tant qu'int en le castant comme suit:
la source
Je ne sais pas si c'était parce que je travaille contre SQL 2000 ou non, mais je devais le faire pour le faire fonctionner.
la source
select cast(SCOPE_IDENTITY() as int)
?Il existe une excellente bibliothèque pour vous simplifier la vie Dapper.Contrib.Extensions. Après avoir inclus cela, vous pouvez simplement écrire:
la source
Si vous utilisez Dapper.SimpleSave:
la source