2

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?

1 Answer 1

1

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

Sign up to request clarification or add additional context in comments.

2 Comments

I had tried using a template but it through exceptions because it was trying to pull values off the object given to it for the parameters which won't work for us. We generate Our parameters through expressions elsewhere and generate the DynamicParameters dynamically. We can't have it trying to pull values off the template. I had seen all those links prior to posting but it didn't work for me with a template (as explained) nor without :/
Alright, then in my view this feature is not for your use case, or you may ask Marc directly with all relevant details on Github issues page

Your Answer

By clicking “Post Your Answer”, you agree to our terms of service and acknowledge you have read our privacy policy.

Start asking to get answers

Find the answer to your question by asking.

Ask question

Explore related questions

See similar questions with these tags.