自动映射多对多关系并添加新对象

时间:2018-10-04 10:04:18

标签: asp.net asp.net-core automapper

我使用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);

我从客户发送带有选择的问题。现在代码可以正常工作,但是问题是,即使它们具有相同的Content,它也会一直将新对象Choices添加到我的数据库中。我要实现的是检测数据库中是否存在收到的选择,并且是否存在->不创建新选择,仅将现有选择的ID添加到多对多关系中。我想我应该在MappingProfile类中以某种方式使用dbcontext,但是我不知道什么是解决此类问题的正确方法。我应该完全使用Automapper吗?

1 个答案:

答案 0 :(得分:0)

因此,因为我无法尝试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应用程序设计方面是否合适,还有其​​他更好的方法来解决此问题吗?