使用 Dapper 时处理大量嵌套对象映射的最佳方式

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

我有一个存储过程,它返回用户正在参与的问卷的当前部分,这是查询的简化版本:

select user_questionnaires.user_id UserId
    ,user_questionnaires.user_questionnaire_id UserQuestionnaireId
    ,questionnaire.questionnaire_id QuestionnaireId
    ,questionnaire_group_link.questionnaire_title QuestionnaireTitle
    ,questionnaire_sections.questionnaire_section_id QuestionnaireSectionId
    ,questionnaire_sections.section_name SectionName
    ,questions.question_id QuestionId
    ,questions.question_name QuestionName
    ,questions.answer_required AnswerRequired
    ,option_choices.option_choice_id OptionChoiceId
    ,option_choices.option_choice_name OptionChoiceText
from user_questionnaires
left join questionnaire
on questionnaire.questionnaire_id = user_questionnaires.questionnaire_id
left join questionnaire_sections
on questionnaire.questionnaire_id = questionnaire_sections.questionnaire_id
left join questions
on questionnaire_sections.questionnaire_section_id = questions.questionnaire_section_id
left join option_groups
on option_groups.option_group_id = questions.option_group_id
left join option_choices
on option_choices.option_group_id = option_groups.option_group_id

以下是我要映射到的类:

public class UserSection
{
    public int UserId;
    public int UserQuestionnaireId;
    public int QuestionnaireId;
    public string? QuestionnaireTitle;
    public QuestionnaireSection? QuestionnaireSection;
}

public class QuestionnaireSection
{
    public int QuestionnaireSectionId;
    public string? SectionName;
    public List<Question>? Questions;
}

public class Question
{
    public int QuestionId;
    public string? QuestionName;
    public bool AnswerRequired;
    public List<OptionChoice>? OptionChoices;
}

public class OptionChoice
{
    public int OptionChoiceId;
    public string? OptionChoiceText;
}

我正在使用 Dapper 调用存储过程并将其映射到一个对象,我目前可以通过以下方式实现所需的输出:

var result = await connection.QueryAsync<UserSection, QuestionnaireSection, Question, OptionChoice, UserSection>(
    "spCurrentSection",
    (userSection, questionnaireSection, question, optionChoice) =>
    {
        if (!lookup.TryGetValue(userSection.UserQuestionnaireId, out var existingUserSection))
        {
            question.OptionChoices ??= new List<OptionChoice>();
            question.OptionChoices.Add(optionChoice);
            questionnaireSection.Questions ??= new List<Question>();
            questionnaireSection.Questions.Add(question);
            userSection.QuestionnaireSection = questionnaireSection;
            lookup[userSection.UserQuestionnaireId] = userSection;
            return userSection;
        }

        userSection = existingUserSection;
        var existingQuestion = userSection.QuestionnaireSection.Questions.FirstOrDefault(q => q.QuestionId == question.QuestionId);

        if (existingQuestion == null)
        {
            question.OptionChoices ??= new List<OptionChoice>();
            question.OptionChoices.Add(optionChoice);
            userSection.QuestionnaireSection.Questions.Add(question);
            lookup[userSection.UserQuestionnaireId] = userSection;
            return userSection;
        }

        if (!existingQuestion.OptionChoices.Any(c => c.OptionChoiceId == optionChoice.OptionChoiceId))
        {
            existingQuestion.OptionChoices.Add(optionChoice);
        }

        lookup[userSection.UserQuestionnaireId] = userSection;
        return userSection;
    },
    param: new { UserId = userid },
    commandType: CommandType.StoredProcedure,
    splitOn: "QuestionnaireSectionId,QuestionId,OptionChoiceId");

return result.Distinct().ToList();

这是处理具有一系列一对一和一对多连接的大量嵌套对象的映射的最佳方法吗?我不确定为此使用映射器是否会更好,但我以前在使用 Dapper 时从未实现过映射器,所以我不确定最好的方法。关于如何以更好的方式达到预期结果的任何建议?

我将实施更多此类调用,并在其中嵌套更多,所以如果有更简单的方法来实现相同的结果,我会洗耳恭听

c# sql orm dapper
© www.soinside.com 2019 - 2024. All rights reserved.