为什么Dapper QueryAsync <t>与具有sproc返回值的Query <t>的行为不同?

时间:2017-08-30 16:23:27

标签: c# sql-server dapper

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

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#repo类,它使用Dapper返回结果或抛出异常:

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整除时,会返回水合对象,否则会抛出异常。

但是,当我创建代码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&#34;没有选择任何列&#34;!

我真的很喜欢这里的模式,并希望异步使用它,为什么失败?我试过打开缓冲,但没有什么区别。

1 个答案:

答案 0 :(得分:0)

目前Dapper并不支持不执行SELECT语句的Async方法 在Github有一个公开的问题:
https://github.com/StackExchange/Dapper/issues/591

你现在所做的是:

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