일반 인자의 Nullable 반환 값

c# dapper generics nullable

문제

Dapper를 사용하여 데이터베이스에 모델을 저장하려고합니다. 업데이트에 사용되는 기존 기본 키 값이있는 int 입출력 매개 변수로 매개 변수를 설정합니다.

public async Task<TKey> SaveAsync<TKey>(IGraph builder, IDataContext context = null)
{
    var parameters = this.GetParametersFromDefinition(builder, DefinitionDirection.In);

    // See if we have a key defined. If not, we assume this is a new insert.
    // Otherwise we pull the key out and assume it's an update.
    PropertyDefinition key = builder.GetKey();

    if (key != null)
    {
        parameters.Add(key.ResolvedName, key.PropertyValue, null, ParameterDirection.InputOutput);
    }
    else
    {
        throw new InvalidOperationException("The data graph did not have a primary key defined for it.");
    }

    await this.ExecuteProcedure(parameters, builder, context);

    object returnedId = parameters.Get<TKey>(key.ResolvedName);
    return returnedId == null ? default(TKey) : (TKey)returnedId;
}

private Task ExecuteProcedure(DynamicParameters parameters, IGraph builder, IDataContext context = null)
{
    ProcedureDefinition mapping = builder.GetProcedureForOperation(ProcedureOperationType.Insert);
    if (string.IsNullOrEmpty(mapping.StoredProcedure))
    {
        throw new InvalidOperationException("No stored procedure mapped to the builder.");
    }

    // Query the database
    return this.SetupConnection(
        context,
        (connection, transaction) => connection.ExecuteAsync(
            mapping.StoredProcedure,
            parameters,
            commandType: CommandType.StoredProcedure,
            transaction: transaction));
}

다음과 같이 호출됩니다.

this.Address.AddressId = await repository.SaveAsync<int>(graph);

매개 변수를 평가할 때 입력 / 출력 매개 변수가 표시됩니다.

동적 매개 변수

그러나 내 저장에서이 줄을 실행하려고하면 :

TKey returnedId = parameters.Get<TKey>(key.ResolvedName);

다음과 같은 예외가 있습니다.

Exception : Caught : "DBNull을 null이 아닌 유형으로 캐스팅하려고 시도합니다! 데이터 스트림이 완료 될 때까지 쿼리 / 아웃 ( 'buffered : false')에 대한 'foreach'다음에 out / return 매개 변수에 값이 업데이트되지 않습니다. 또는 GridReader가 QueryMultiple에 대해 삭제 된 후) "(System.ApplicationException) System.ApplicationException이 catch되었습니다."DBNull을 null이 아닌 형식으로 캐스팅하려고 시도했습니다. 데이터 스트림이 반환 될 때까지 반환 / 반환 매개 변수에 값이 업데이트되지 않습니다 쿼리 (..., 버퍼링 : false)에 대한 'foreach'이후 또는 GridReader가 QueryMultiple에 대해 삭제 된 후 완료) "시간 : 2011 년 7 월 21 일 10:19:48 PM 주제 : [7200]

나는 이것이 정수이기 때문에이 경우 nullable이 아닌 일반적인 유형의 문제라고 가정하고 있습니다. Dapper가 항상 nullable을 반환하기 때문에 이것이 가능한가? 방금 출력에 무언가가 할당되었는지 확인하기 위해 상수 값을 저장 프로 시저에 OUTPUT으로 할당했습니다.

nullable을 반환하는 dapper 주위에서 어떻게 작동 int? 내에서 전달하는 유일한 방법 int? 제네릭 유형으로?

최신 정보

나는이 접근법을 사용하여 그것을 해결할 수 있었다. 그래서 아직 답변으로 게시하지 않습니다. 기한이 끝나면 다른 사람이 더 좋은 아이디어를 갖고 있지 않으면 답을 게시 할 것입니다.

object returnedId = parameters.Get<TKey>(key.ResolvedName);
if (returnedId == null)
{
    return default(TKey);
}

return (TKey)returnedId;

수락 된 답변

DBNull이 유효한 값이고 default (TKey) (예 : default (int) = 0)가 아닌 다른 값을 의미해야하고 TKey가 항상 값 유형이면 TKey를 다음과 같이 struct로 제한합니다.

public async Task<TKey?> SaveAsync<TKey>(IGraph builder, IDataContext context = null) where TKey : struct
{
    ...
}

그런 다음 키를 얻으십시오.

TKey? returnedId = parameters.Get<TKey?>(key.ResolvedName);

SaveAsync의 반환 유형은 키가 null 일 수 있음을 나타냅니다. 키가 결코 null이 아니어야하고 DBNull이 기본값 (TKey)으로 기본 설정되어야하는 경우 다음을 사용하면됩니다.

public async Task<TKey?> SaveAsync<TKey>(IGraph builder, IDataContext context = null) where TKey : struct
{
    ...
    return parameters.Get<TKey?>(key.ResolvedName).GetValueOrDefault();
}


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