DynamicParameters.Output<T> 不会将输出映射到模型

Posted

技术标签:

【中文标题】DynamicParameters.Output<T> 不会将输出映射到模型【英文标题】:DynamicParameters.Output<T> doesn't map the output to the model 【发布时间】:2016-10-06 19:19:45 【问题描述】:

我正在使用 Dapper 执行一个返回两个输出参数的存储过程。一个是 xml 数据类型,另一个是整数。我正在尝试在DynamicParameters 类型上使用Output&lt;T&gt; 方法。但是,当我使用它时,分配的值始终是default(T),所以在这个例子中TotalNoOfUsers 是0。

这是我正在使用的示例模型。

public class Foo

    public string Xml  get; set; 

    public int NumberOfUsers  get; set; 

以下是我为演示该行为而编写的单元测试。

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

但是我可以使用Get&lt;T&gt; 方法,它会给我返回预期的输出。

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

我是否错误地使用了Output&lt;T&gt;

【问题讨论】:

【参考方案1】:

查看以下 Dapper issue,还合并了一个修复 here。 另请查看 Marc 对另一个查询的回复 here

简单的一点是在上面粘贴的代码中,它不起作用的地方是,当您创建DynamicParameter 以通过表达式映射输出时,需要一个用于映射的对象模板,它需要调用以下构造函数,不是默认的:

public DynamicParameters(object template);

发布你当然需要告诉ParameterDirection,因为它已经在代码中完成了,否则默认情况下它会将所有内容视为InputParameter并且仍然会导致错误。

由于您没有传递模板,因此输出无法映射到正确的值,输出结果为 0

【讨论】:

我曾尝试使用模板,但它通过异常处理,因为它试图从给它的对象中提取对我们不起作用的参数的值。我们通过其他地方的表达式生成我们的参数,并动态生成 DynamicParameters。我们不能让它试图从模板中提取值。我在发布之前已经看到了所有这些链接,但它对我来说不管用模板(如解释)还是没有:/ 好吧,那么在我看来这个功能不适合你的用例,或者你可以直接向 Marc 询问 Github 问题页面上的所有相关细节

以上是关于DynamicParameters.Output<T> 不会将输出映射到模型的主要内容,如果未能解决你的问题,请参考以下文章