Johnathon Sullinger
Johnathon Sullinger

Reputation: 7414

DynamicParameters.Output<T> doesn't map the output to the model

I'm using Dapper to execute a stored procedure that returns back two output parameters. Once is a xml data type and the other is an integer. I'm trying to use the Output<T> method on the DynamicParameters Type. When I use it however, the value assigned is always default(T), so in this example TotalNoOfUsers is 0.

This is my example model i'm working off of.

public class Foo
{
    public string Xml { get; set; }

    public int NumberOfUsers { get; set; }
}

The following is a unit test that I wrote to demonstrate the behavior.

[TestMethod]
public async Task Test()
{
    var foo = new Foo();
    var connection = new SqlConnection(this.connectionString);
    await connection.OpenAsync();

    var parameters = new DynamicParameters();
    parameters.Add("ApplicationInstanceRoleId", this.roleId);
    parameters.Add("TotalNoOfUsers", 0, DbType.Int32, ParameterDirection.Output);
    parameters.Output(foo, output => output.NumberOfUsers);

    await connection.ExecuteAsync(
        "USP_Get_UsersAndAccessControlXML4ApplicationRole",
        parameters,
        commandType: CommandType.StoredProcedure);

   Assert.AreNotEqual(0, foo.NumberOfUsers);
}

I can however use the Get<T> method and it will give me back the expected output.

[TestMethod]
public async Task Test()
{
    var foo = new Foo();
    var connection = new SqlConnection(this.connectionString);
    await connection.OpenAsync();

    var parameters = new DynamicParameters();
    parameters.Add("ApplicationInstanceRoleId", this.roleId);
    parameters.Add("TotalNoOfUsers", 0, DbType.Int32, ParameterDirection.Output);

    await connection.ExecuteAsync(
        "USP_Get_UsersAndAccessControlXML4ApplicationRole",
        parameters,
        commandType: CommandType.StoredProcedure);

    foo.NumberOfUsers = parameters.Get<int>("TotalNoOfUsers");
    Assert.AreNotEqual(0, foo.NumberOfUsers);
}

Am I using the Output<T> incorrectly?

Upvotes: 2

Views: 4500

Answers (1)

Mrinal Kamboj
Mrinal Kamboj

Reputation: 11478

Check out the following Dapper issue, also a fix has been merged here. Also check Marc's response to another query here

Simple point is in the code pasted above, where its not working, is while you create the DynamicParameter to map the Output via expression, in needs an object template for the mapping, it needs the following constructor to be called, not the default one:

public DynamicParameters(object template);

Post that you certainly need to tell the ParameterDirection as done already in the code, else it will consider everything by default as InputParameterand still lead to an error.

Since you are not passing a template, that's why Output is not able to map to the correct values, output result is 0

Upvotes: 1

Related Questions