Logo Questions Linux Laravel Mysql Ubuntu Git Menu
 

How can I use Dapper's strongly-typed query parameters with Sybase ASE?

Dapper can pass query parameters as anonymous objects, and supports any ADO.NET data provider. However, when running the following query against the Sybase 15 ADO.NET drivers:

using (var connection = new AseConnection("..."))
{
    connection.Open();

    var results = connection.Query<Foo>(
        "dbo.sp_columns", new { table_name = "dbo.sysusers"}, 
        commandType: CommandType.StoredProcedure);
}

... the following error is thrown:

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

Changing it to a Dapper DynamicParameters set with "@table_name" also doesn't work.

How can I pass strongly-typed parameters to Sybase with Dapper?

like image 424
Richard Dingwall Avatar asked Oct 19 '11 15:10

Richard Dingwall


1 Answers

As far as I can tell, the reason seems to be something to do with Sybase's AseParameter class, and not correctly mapping DbType to AseDbType values.

You can work around the problem by defining a custom Dapper IDynamicParameters set, and populating it with AseParameter objects directly:

public class AseCommandParameters : List<AseParameter>, SqlMapper.IDynamicParameters
{
    public void AddParameters(IDbCommand command, SqlMapper.Identity identity)
    {
        foreach (var parameter in this)
            command.Parameters.Add(parameter);
    }
}

And then passing an instance into the query:

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);
}

This works, and also lets you specify the AseDbType for each parameter.

like image 116
Richard Dingwall Avatar answered Sep 23 '22 11:09

Richard Dingwall