Dapper QueryAsync를 사용하여 단일 객체 반환

asynchronous c# dapper repository

문제

불행히도 우리 DB는 90 년대로 거슬러 올라갑니다. 그 유산은 너무 강해서 대부분의 CRUD 작업을 수행하기 위해 여전히 SP를 사용하고 있습니다. 그러나 Dapper가 꽤 잘 어울리는 것 같아요. 우리는 방금 놀았습니다.

그러나 단일 데이터 행을 처리하는 방법에 대해 조금 걱정이됩니다. 이 경우 QueryAsync를 사용하여 ID를 전달하는 SP를 호출합니다. 보시다시피 개체가 비동기 호출 (*) 외부로 반환 됩니다.

문제가 될 건가요? 그렇다면 누구나 그것을 어떻게 처리 할 수 ​​있는지 알고 있습니까? 대신 QuerySync를 사용해야합니까?

public class SchemePolicyRepository : ISchemePolicyRepository
{
    private readonly SqlConnection sql;

    protected SchemePolicyRepository(SqlConnection connection)
    {
        sql = connection;
    }
    ... 
    public async Task<SchemePolicy> GetById(string id)
    {
        var schemePolicy = await sql.QueryAsync<SchemePolicy>("risk.iE_GetSchemePolicyById",
            new { Id = id },
            commandType: CommandType.StoredProcedure);
        return schemePolicy != null ? schemePolicy.FirstOrDefault() : null;
    }
    ...
}

(*) FirstOfDefault ()에 의해 반환 된 SchemePolicy 객체는 비동기 메소드가 아닙니다.

수락 된 답변

우선, null check 가 필요하다고 생각하지 않습니다. Dapper는 쿼리에 대해 0 행을 반환합니다. SQL Server 에서는 TRUE 이지만 다른 RDBMS에서는 같아야합니다. 그래서 이거

return schemePolicy != null ? schemePolicy.FirstOrDefault() : null;

간단히 다음과 같이 쓸 수있다.

return schemePolicy.FirstOrDefault();

이제 진짜 관심사를 다루기 위해 언급 한 바 있습니다.

개체가 비동기 호출 (*) 외부로 반환됩니다.

그건 사실이 아니야. 쿼리를 실행 한 후에는 객체를 얻는 방법 쓰면됩니다. 다음은 두 가지 코드 세트가 동일한 동작을 산출합니다.

var schemePolicy = await sql.QueryAsync<SchemePolicy>("sp", {rest of code});
return schemePolicy.FirstOrDefault();

var schemePolicy = sql.QueryAsync<SchemePolicy>("sp", {rest of code});
return schemePolicy.Result.FirstOrDefault();

이제는 GetById 를 호출하여 (1) 메서드가 다른 스레드를 차단하지 않으며 (2) 쿼리 실행이 끝나면 대상 개체 만 가져올 수 있는지에 대한 관심이 실제로 있습니다. 콘솔 앱 스 니펫은 다음과 같이 테스트 할 수 있습니다.

static async void GetValue()
{
    var repo = new SchemePolicyRepository(new DbManager()); // creates an open connection 
    var result = await repo.GetById();
    Console.WriteLine(result);
}

static void Main(string[] args)
{
    GetValue();   
    Console.WriteLine("Query is running...");
    Console.ReadKey();
}

이 테스트는 결과적으로 GetById 메서드를 호출하는 GetValue 가 나머지 코드를 차단하지 않는다는 것을 보여줍니다. 또한 쿼리가 처리 될 때까지 FirstOrDefault 에서 아무 것도 반환되지 않습니다.

다음은 개념이 유효한지 (SQL Server 2008 이상에서 작동하는 코드) 누군가가 시도하고 싶어하는지 확인하기위한 쿼리의 지원 코드입니다.

public async Task<int> GetById()
{
    var sql = @"
WAITFOR DELAY '00:00:05';
select 1 where 1=1";

    var result = await {the_open_connection}.QueryAsync<int>(sql);    
    return result.FirstOrDefault();
}


아래 라이선스: CC-BY-SA with attribution
와 제휴하지 않음 Stack Overflow
이 KB는 합법적입니까? 예, 이유를 알아보십시오.
아래 라이선스: CC-BY-SA with attribution
와 제휴하지 않음 Stack Overflow
이 KB는 합법적입니까? 예, 이유를 알아보십시오.