为什么Dapper QueryAsync< T>行为与Query< T>不同与存储返回值? [英] Why does Dapper QueryAsync<T> behave differently from Query<T> with sproc return values?

查看:305
本文介绍了为什么Dapper QueryAsync< T>行为与Query< T>不同与存储返回值?的处理方法,对大家解决问题具有一定的参考价值,需要的朋友们下面随着小编来一起学习吧!

问题描述

我有一个执行检查的存储过程,并返回行或非零返回值:

I have a stored procedure that performs a check, and returns either a row or a non-zero return value:

CREATE PROCEDURE dbo.ConditionalGet
    @ID INT
AS
BEGIN

    -- this is a silly made up condition just to test the issue
    IF @ID % 2 = 1
    BEGIN
        RETURN -1
    END

    SELECT *
    FROM MyTable
    WHERE ID = @ID

    RETURN 0
END

我有一个C#回购类Dapper返回结果或引发异常:

And I have a C# repo class that uses Dapper to return the result or throw an exception:

public class Repo
{
    public MyClass Get(int id)
    {
        using (var conn = GetSqlConnection())
        {
            var p = new { ID = id };
            var pWithReturnValue = new DynamicParameters(p);
            p.Add("return", null, DbType.Int32, ParameterDirection.ReturnValue);

            var result = conn.Query<MyClass>("dbo.ConditionalGet", p, commandType: CommandType.StoredProcedure);

            var errorCode = p.Get<int>("return");
            if (errorCode != 0)
                throw new RepositoryGetException(errorCode);

            return result.FirstOrDefault();
        }
    }
}

这可以按预期工作:当id可被2整除时,将返回水合对象,否则将引发异常。

And this works as expected: when id is divisible by 2, the hydrated object is returned, otherwise an exception is thrown.

但是,当我使代码异步时,这将失败!

HOWEVER, this fails when I make the code Async!

public class Repo
{
    public async Task<MyClass> Get(int id)
    {
        using (var conn = GetSqlConnection())
        {
            var p = new { ID = id };
            var pWithReturnValue = new DynamicParameters(p);
            p.Add("return", null, DbType.Int32, ParameterDirection.ReturnValue);
            // this is the only change!
            var result = await conn.QueryAsync<MyClass>("dbo.ConditionalGet", p, commandType: CommandType.StoredProcedure);

            var errorCode = p.Get<int>("return");
            if (errorCode != 0)
                throw new RepositoryGetException(errorCode);

            return result.FirstOrDefault();
        }
    }
}

这将引发InvalidOperationException No

This throws an InvalidOperationException "No columns were selected"!

我真的很喜欢这里的模式,并且希望异步使用它,那为什么会失败呢?我试过打开和关闭缓冲区,但没有任何效果。

I really like the pattern here and would like to use it asynchronously, so why the failure? I've tried turning buffering off and on and it didn't make a difference.

推荐答案

当前Dapper不支持不执行SELECT语句的异步方法。

Github中存在一个与此相关的未解决问题:

> https://github.com/StackExchange/Dapper/issues/591

Currently Dapper doesn't support for Async methods that no perform a SELECT statement.
There is a open issue about that in Github:
https://github.com/StackExchange/Dapper/issues/591

您做什么现在是这样的:

What you do for now is something like:

ALTER PROCEDURE dbo.ConditionalGet
    @ID INT,
    @Output INT OUTPUT
AS
BEGIN

    -- this is a silly made up condition just to test the issue
    IF @ID % 2 = 1
    BEGIN
        SET @Output = -1
    END
    ELSE BEGIN
        SET @Output = 0
    END

    SELECT *
    FROM MyTable
    WHERE ID = @ID
END

这篇关于为什么Dapper QueryAsync&lt; T&gt;行为与Query&lt; T&gt;不同与存储返回值?的文章就介绍到这了,希望我们推荐的答案对大家有所帮助,也希望大家多多支持IT屋!

查看全文
相关文章
登录 关闭
扫码关注1秒登录
发送“验证码”获取 | 15天全站免登陆