首页 > 解决方案 > 自动映射多对多关系并添加新对象

问题描述

我使用 EF Core 映射了以下模型:

    public class Choice
{
    public int Id { get; set; }
    public string Content { get; set; }
    public List<ChoicesQuestions> ChoicesQuestions { get; set; }
}

  public class ChoicesQuestions
{
    public int ChoiceId { get; set; }
    public Choice Choice { get; set; }
    public int QuestionId { get; set; }
    public Question Question { get; set; }
}

   public class Question
{
    public int Id { get; set; }
    public string Content { get; set; }
    public List<ChoicesQuestions> ChoicesQuestions { get; set; }
}

还有资源:

    public class ChoiceResource
{
    public int Id { get; set; }
    public string Content { get; set; }
}

    public class AddQuestionResource
{
    public int Id { get; set; }
    public string Content { get; set; }
    public List<ChoiceResource> Choices { get; set; }
}

我有以下映射:

  CreateMap<ChoicesQuestions, ChoiceResource>()
            .ForMember(d => d.Id, opt => opt.MapFrom(c => c.ChoiceId))
            .ForMember(d => d.Content, opt => opt.MapFrom(c => c.Choice.Content));

   CreateMap<ChoiceResource, ChoicesQuestions>()
    .ForMember(d => d.ChoiceId, opt => opt.Ignore())
    .ForMember(d => d.Choice, opt => opt.Ignore())
    .AfterMap((o, c) =>
    {
        c.Choice = new Choice();
        c.Choice.Content = o.Content;
    });

       CreateMap<AddQuestionResource, Question>()
       .ForMember(o => o.ChoicesQuestions, opt => opt.MapFrom(x => x.Choices));

        CreateMap<Question, AddQuestionResource>();

我在控制器中使用此代码(从客户端 addQuestionResource 发送):

  var question = _mapper.Map<Question>(addQuestionResource);

从客户我发送带有选择的问题。现在代码工作正常,但问题是,它一直在向我的数据库添加新对象选择,即使它们具有相同的内容。我想要实现的是检测数据库中是否存在接收到的选项,如果存在 - >不创建新选项,只添加现有一对多对多关系的 Id。我想我应该在 MappingProfile 类中以某种方式使用 dbcontext,但我不知道解决这类问题的正确方法是什么。我应该为此使用 Automapper 吗?

标签: asp.netasp.net-coreautomapper

解决方案


所以因为我无法尝试 Lucian (Automapper.Collection) 提出的解决方案,所以我尝试了其他方法。一个可行的方法是实现 ValueResolver 接口:

    public class ChoiceResolver : IValueResolver<ChoiceResource, ChoicesQuestions, Choice>
{
    private readonly PollContext _pollContext;
    public ChoiceResolver(PollContext pollContext)
    {
        _pollContext = pollContext;
    }

    public Choice Resolve(ChoiceResource source, ChoicesQuestions destination, Choice destMember, ResolutionContext context)
    {
        var choice = _pollContext.Choices.SingleOrDefault(a => a.Content == source.Content);
        if (choice != null)
        {
            return choice;
        }
        else
        {
            var newChoice = new Choice();
            newChoice.Content = source.Content;
            return newChoice;
        }
    }
}

和我的映射:

    CreateMap<ChoiceResource, ChoicesQuestions >()
            .ForMember(d => d.ChoiceId, opt => opt.Ignore())
            .ForMember(d => d.Choice, opt => opt.ResolveUsing<ChoiceResolver>());

所以我解决了这个问题,我唯一的问题是这个解决方案是否适合 Web 应用程序的设计,是否还有其他更好的方法来解决这个问题?


推荐阅读