Dapper .NET: problèmes avec les requêtes paramétrées par la structure

c# dapper

Question

J'essaie d'utiliser des structures comme paramètres dans les requêtes Dapper . Cela ne marche pas pour moi. Mais il semble que cela devrait marcher .

Un exemple défaillant:

struct Simple { public int ID; }

[TestMethod]
public void StructParameter()
{
    int result = Db.Query<int>("select [ID] = @ID", new Simple { ID = 123 }).First();
    result.Should().Be(123);
}

Un exemple pratique:

[TestMethod]
public void AnonymousParameter()
{
    int result = Db.Query<int>("select [ID] = @ID", new { ID = 123 }).First();
    result.Should().Be(123);
}

L'erreur lancée dans le premier cas:

System.Data.SqlClient.SqlException: Must declare the scalar variable "@ID".
Result StackTrace:  
at System.Data.SqlClient.SqlConnection.OnError(SqlException exception, Boolean breakConnection, Action`1 wrapCloseInAction)
   at System.Data.SqlClient.SqlInternalConnection.OnError(SqlException exception, Boolean breakConnection, Action`1 wrapCloseInAction)
   at System.Data.SqlClient.TdsParser.ThrowExceptionAndWarning(TdsParserStateObject stateObj, Boolean callerHasConnectionLock, Boolean asyncClose)
   at System.Data.SqlClient.TdsParser.TryRun(RunBehavior runBehavior, SqlCommand cmdHandler, SqlDataReader dataStream, BulkCopySimpleResultSet bulkCopyHandler, TdsParserStateObject stateObj, Boolean& dataReady)
   at System.Data.SqlClient.SqlDataReader.TryConsumeMetaData()
   at System.Data.SqlClient.SqlDataReader.get_MetaData()
   at System.Data.SqlClient.SqlCommand.FinishExecuteReader(SqlDataReader ds, RunBehavior runBehavior, String resetOptionsString)
   at System.Data.SqlClient.SqlCommand.RunExecuteReaderTds(CommandBehavior cmdBehavior, RunBehavior runBehavior, Boolean returnStream, Boolean async, Int32 timeout, Task& task, Boolean asyncWrite, SqlDataReader ds)
   at System.Data.SqlClient.SqlCommand.RunExecuteReader(CommandBehavior cmdBehavior, RunBehavior runBehavior, Boolean returnStream, String method, TaskCompletionSource`1 completion, Int32 timeout, Task& task, Boolean asyncWrite)
   at System.Data.SqlClient.SqlCommand.RunExecuteReader(CommandBehavior cmdBehavior, RunBehavior runBehavior, Boolean returnStream, String method)
   at System.Data.SqlClient.SqlCommand.ExecuteReader(CommandBehavior behavior, String method)
   at System.Data.SqlClient.SqlCommand.ExecuteDbDataReader(CommandBehavior behavior)
   at System.Data.Common.DbCommand.System.Data.IDbCommand.ExecuteReader(CommandBehavior behavior)
   at Dapper.SqlMapper.<QueryImpl>d__11`1.MoveNext() in d:\Dev\dapper-dot-net\Dapper NET40\SqlMapper.cs:line 1553
   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 d:\Dev\dapper-dot-net\Dapper NET40\SqlMapper.cs:line 1443
   ...

J'utilise la version 1.38 de Dapper.


Par suggestion de Dirk, la propriété au lieu du fichier fonctionne parfaitement:

struct Simple {
    public int ID { get; set; }
}

Réponse acceptée

Le problème n'est pas causé par l'utilisation de structures, mais par l'utilisation de champs au lieu de propriétés.

Si vous modifiez struct Simple en class Simple cela ne fonctionnera toujours pas car le lecteur de paramètres ne crée que du code IL pour lire les propriétés.

Changer le champ ID dans une propriété le résoudra.



Sous licence: CC-BY-SA with attribution
Non affilié à Stack Overflow
Est-ce KB légal? Oui, apprenez pourquoi
Sous licence: CC-BY-SA with attribution
Non affilié à Stack Overflow
Est-ce KB légal? Oui, apprenez pourquoi