다퍼 다중 매핑 문제

dapper

문제

다음 코드 블록에 대해 "다중 매핑 API를 사용할 때 Id가 아닌 키가있는 경우 splitOn 매개 변수를 설정하십시오"오류가 계속 발생합니다.

var accounts = DbConnection.Query<Account, Branch, Application, Account>(
            "select Accounts.*, SplitAccount = '', Branches.*, SplitBranch = '', Applications.*" +
            " from Accounts" +
            "    join Branches" +
            "       on Accounts.BranchId = Branches.BranchId" +
            "    join Applications" +
            "       on Accounts.ApplicationId = Applications.ApplicationId" +
            " where Accounts.AccountId <> 0",
            (account, branch, application) =>
                {
                    account.Branch = branch;
                    account.Application = application;
                    return account;
                }, splitOn : "SplitAccount, SplitBranch"
            ).AsQueryable();

해결 방법으로 splitOn에 SplitAccount 및 SplitBranch를 사용하고 있습니다.

내가 뭘 놓친거야?

감사

편집하다:

나는 약간의 테스트를 정리했다. 클래스의 가벼운 버전과 새로운 쿼리가 아래에있다.

public class AccountLight
{
    public int AccountId { get; set; }
    public string AccountNumber { get; set; }
    public BranchLight Branch { get; set; }
    public ApplicationLight Application { get; set; }
}

public class BranchLight
{
    public int BranchId { get; set; }
    public string BranchNumber { get; set; }
}

public class ApplicationLight
{
    public int ApplicationId { get; set; }
    public string ApplicationCode { get; set; }
}

var accounts2 = DbConnection.Query<AccountLight, BranchLight, ApplicationLight, AccountLight>(
    "select Accounts.AccountId, Accounts.AccountNumber," +
    "       Branches.BranchId, Branches.BranchNumber," +
    "       Applications.ApplicationId, Applications.ApplicationCode" +
    " from Accounts" +
    "    inner join Branches" +
    "       on Accounts.BranchId = Branches.BranchId" +
    "    inner join Applications" +
    "       on Accounts.ApplicationId = Applications.ApplicationId" +
    " where Accounts.AccountId <> 0",
    (account, brach, application) =>
    {
        account.Branch = brach;
        account.Application = application;
        return account;
    }, 
    commandType: CommandType.Text,
    splitOn: "AccountId, BranchId"
    ).AsQueryable();

수락 된 답변

Dapper의 소스 코드를 디버깅 한 지 몇 시간 만에 마침내 문제가 발견되어 매우 흥미 롭습니다.

여러 splitOn 필드가 제공되면 Dapper는 쉼표를 기반으로 분할을 수행합니다 (예 : var splitits = splitOn.Split ( ','). ToArray ()). 그런 다음 모든 레코드 세트 필드를 반복하고 위의 배열을 기반으로 오브젝트를 분할합니다. 꽤 해협.

이제 재미있는 부분 : splitOn 필드를 제공 할 때 쉼표 뒤에 "SPACEId, BranchId"와 같은 여분의 공간이 있었으며 그 작은 공간이 원인이었습니다. Split () 후에 BranchId 필드에 추가 공간이 포함되어 레코드 세트의 모든 필드와 일치하지 못했습니다.

이 문제를 해결하는 데는 두 가지 방법이 있습니다.

  1. 쉼표 뒤에 여분의 공백을 사용하지 마십시오. 나는 개인적으로 중독되어 있습니다. SQL의 오래된 습관.
  2. Dapper의 GenerateDeserializers 메소드를 수정하고 다음과 같이 변경합니다. var currentSplit = var currentSplit = splitits [splitIndex] .Trim () 또는 이와 유사한 항목으로 [splitIndex]를 분할합니다. 그게 내가 로컬 사본을 위해 한 일이다.

다음은 코드 스냅 샷입니다.

    private static Func<IDataReader, object>[] GenerateDeserializers(Type[] types, string splitOn, IDataReader reader)
    {
        int current = 0;
        var splits = splitOn.Split(',').ToArray();
        var splitIndex = 0;

        Func<Type, int> nextSplit = type =>
        {
            var currentSplit = splits[splitIndex].Trim();
            if (splits.Length > splitIndex + 1)
            {
                splitIndex++;
            }

최신 정보:

위의 수정 사항이 병합되었습니다. https://github.com/SamSaffron/dapper-dot-net/commit/399db17e5aa6f1eefaf8fdccff827020be8e6cbb



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