Comment puis-je utiliser les paramètres de la requête fortement typées Dapper avec Sybase ASE?
-
27-10-2019 - |
Question
Dapper peut passer des paramètres de requête comme des objets anonymes, et prend en charge toute ADO fournisseur de données .NET. Cependant, lors de l'exécution de la requête suivante sur les Sybase 15 pilotes ADO.NET:
using (var connection = new AseConnection("..."))
{
connection.Open();
var results = connection.Query<Foo>(
"dbo.sp_columns", new { table_name = "dbo.sysusers"},
commandType: CommandType.StoredProcedure);
}
... l'erreur suivante est générée:
Sybase.Data.AseClient.AseException: Procedure sp_columns expects parameter @table_name, which was not supplied.
at Sybase.Data.AseClient.AseCommand.ᜁ(Int32 A_0)
at Sybase.Data.AseClient.AseCommand.ᜄ()
at Sybase.Data.AseClient.AseCommand.ᜀ(CommandBehavior A_0)
at Sybase.Data.AseClient.AseCommand.System.Data.IDbCommand.ExecuteReader()
at Dapper.SqlMapper.<QueryInternal>d__13`1.MoveNext() in SqlMapper.cs: line 579
at System.Collections.Generic.List`1..ctor(IEnumerable`1 collection)
at System.Linq.Enumerable.ToList(IEnumerable`1 source)
at Dapper.SqlMapper.Query(IDbConnection cnn, String sql, Object param, IDbTransaction transaction, Boolean buffered, Nullable`1 commandTimeout, Nullable`1 commandType) in SqlMapper.cs: line 536
Modification à un ensemble de DynamicParameters
Dapper avec « @table_name » ne fonctionne pas non plus.
Comment puis-je passer des paramètres fortement typé Sybase avec Dapper?
La solution
Pour autant que je peux dire, la raison semble être quelque chose à voir avec la classe AseParameter
de Sybase, et non la cartographie correctement DbType
aux valeurs AseDbType
.
Vous pouvez contourner le problème en définissant un ensemble Dapper personnalisé IDynamicParameters
, et le peuplant avec AseParameter
objets directement:
public class AseCommandParameters : List<AseParameter>, SqlMapper.IDynamicParameters
{
public void AddParameters(IDbCommand command, SqlMapper.Identity identity)
{
foreach (var parameter in this)
command.Parameters.Add(parameter);
}
}
Et en faisant passer une instance dans la requête:
using (var connection = new AseConnection("..."))
{
connection.Open();
var parameters = new AseCommandParameters
{
new AseParameter("@table_name", "dbo.sysusers")
};
var results = connection.Query<Foo>("dbo.sp_columns", parameters,
commandType: CommandType.StoredProcedure);
}
Cela fonctionne, et permet également de spécifier le AseDbType
pour chaque paramètre.