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
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();
}
}
}
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();
}
}
}
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.
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
The technical post webpages of this site follow the CC BY-SA 4.0 protocol. If you need to reprint, please indicate the site URL or the original address.Any question please contact:yoyou2525@163.com.