Dapper .NET Core 中的多重映射问题

问题描述 投票:0回答:1

我有以下 2 个模型类:

public class EnrollableClass
{
    public long EnrollableClassId { get; set; }
    public string ClassEnrollmentCode { get; set; } = string.Empty;
    public string ClassTitle { get; set; } = string.Empty;
    public string ClassGrade { get; set; } = string.Empty;
    public DateTime CreatedDate { get; set; } = DateTime.UtcNow;
    public DateTime LastUpdated { get; set; } = DateTime.UtcNow;
    public ICollection<EnrollableClassTeacher> EnrollableClassTeachers { get; set; }
    public ICollection<ClassUnit> ClassUnits { get; set; } = new List<ClassUnit>();
    public ICollection<EnrollableClassStudent> EnrollableClassStudents { get; set; }
}

public class ClassUnit
{
    public long UnitId { get; set; }
    public string UnitTitle { get; set; }
    public string StudentVisibility { get; set; }
    public long EnrollableClassId { get; set; }
    public EnrollableClass EnrollableClass { get; set; }
}

我正在尝试使用此方法恢复

EnrollableClass
及其单位,但它没有映射 ClassUnit:

public async Task<EnrollableClass> GetEnrollleableClassWithUnitData(long EnrollableClassId)
{
    var query = @"SELECT EC.[EnrollableClassId], [ClassEnrollmentCode], [ClassTitle], [ClassGrade], [CreatedDate], [LastUpdated],
                    [ClassUnitId], CU.[EnrollableClassId], [UnitCMSDocId], [IsVisible]
                    FROM [spark].[EnrollableClass] EC
                    LEFT JOIN spark.ClassUnit CU ON EC.EnrollableClassId=CU.EnrollableClassId
                    WHERE EC.EnrollableClassId=@EnrollableClassId";

    using (var connection = _context.CreateConnection())
    {
         var result = await connection.QueryAsync<EnrollableClass, ClassUnit, EnrollableClass>(query,
                (enrollableClass, classUnit) =>
                {
                    enrollableClass.ClassUnits.Add(classUnit);
                    return enrollableClass;
                },
                new { EnrollableClassId = EnrollableClassId },
                splitOn: "EnrollableClassId, ClassUnitId");
            return result.FirstOrDefault();
    }
}

记录一下,这是查询的结果集:

EnrollableClassId   ClassEnrollmentCode     ClassTitle  ClassGrade  
CreatedDate     LastUpdated     ClassUnitId     EnrollableClassId   
UnitCMSDocId    IsVisible

1   R8W60G  asdf    5th 2023-10-28 16:32:21.517 2023-10-28 16:32:21.517 2   1   155 1

1   R8W60G  asdf    5th 2023-10-28 16:32:21.517 2023-10-28 16:32:21.517 3   1   156 1

运行时没有任何反应,抛出classUnit为null的异常。我尝试了各种 splitOn 参数,包括仅

EnrollableClassID
和仅
ClassUnitId
以及组合。这是一对多,所以我一定错过了一些明显的东西。

sql .net .net-core dapper
1个回答
0
投票

再次查看您的代码,我意识到您实际上不需要我在评论中链接的字典解决方案。具体方法如下:

public async Task<EnrollableClass> GetEnrolleableClassWithUnitData(long EnrollableClassId)
{
    var query = @"SELECT EC.[EnrollableClassId], [ClassEnrollmentCode], [ClassTitle], [ClassGrade], [CreatedDate], [LastUpdated],
                    [ClassUnitId], CU.[EnrollableClassId], [UnitCMSDocId], [IsVisible]
                    FROM [spark].[EnrollableClass] EC
                    LEFT JOIN spark.ClassUnit CU ON EC.EnrollableClassId=CU.EnrollableClassId
                    WHERE EC.EnrollableClassId=@EnrollableClassId";

    using (var connection = _context.CreateConnection())
    {
         EnrollableClass enrollableClass = null;
         var result = await connection.QueryAsync<EnrollableClass, ClassUnit, EnrollableClass>(query,
                (e, classUnit) =>
                {
                    if (enrollableClass = null)
                    {
                        enrollableClass = e;
                    }
                    enrollableClass.ClassUnits.Add(classUnit);
                    return null;
                },
                new { EnrollableClassId = EnrollableClassId },
                splitOn: "ClassUnitId");
        return enrollableClass;
    }
}

诀窍是仅创建一个

EnrollableClass
并将单位添加到其中。 map 函数可以返回 null,因为您没有使用它的输出,并且只需要一个 splitOn 将结果集一分为二。

© www.soinside.com 2019 - 2024. All rights reserved.