asp.net - 自动映射多对多关系并添加新对象
问题描述
我使用 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 吗?
解决方案
所以因为我无法尝试 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 应用程序的设计,是否还有其他更好的方法来解决这个问题?
推荐阅读
- twitter-bootstrap - 我的 Bootstrap 布局包含我想删除的大间隙
- c - 拖动滚动实现?
- python - 根据另一列中的非空值计算一列中的唯一值
- spring-boot - 生成的字段与我在实体中定义的不匹配
- python - 字典在迭代过程中改变了大小,在深度复制之后,python
- swiftui - 将消息从子视图发布到父视图
- python - Windows bash shell 显示错误的 Python 版本
- version - 如何在 Racket 中获取已安装软件包的版本号
- javascript - 出现错误:DeprecationWarning: Buffer(),仅在使用 IISNode 部署网站时
- filter - PowerBI中高级分组完成的百分比?