为什么Dapper QueryAsync< T>行为与Query< T>不同与存储返回值? [英] Why does Dapper QueryAsync<T> behave differently from Query<T> with sproc return values?
问题描述
我有一个执行检查的存储过程,并返回行或非零返回值:
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< T>行为与Query< T>不同与存储返回值?的文章就介绍到这了,希望我们推荐的答案对大家有所帮助,也希望大家多多支持IT屋!