问题
我有一个域模型,其中包含一个修订系统。在概念上它看起来像这样:
Model -> ModelDetails
模型包含与其他对象的所有关系,并且ICollection
为ModelDetails
。它还有一个显示最新版本的details
属性。到目前为止,我已经通过手动编码将所有内容映射到视图模型。这些基本上是Model
和ModelDetails
(details属性)对象的组合。问题在于定义viewmodel的映射来自Model
作为Details
属性(ModelDetails
模型)。
通过下面显示的示例,我可以通过使用额外的调用来实现它,但是我需要将调用放在每个转换位置而不是仅仅一个映射调用。另一个复杂性是因为关系被映射,我无法处理关系atm的修订。
域名模型
public class Model : RevisionBasedModel<Revisions.ModelDetails>
{
public int Id { get; set; }
public virtual ICollection<ModelTwo> RelationExample { get; set; }
= new HashSet<ModelTwo>();
}
public abstract class RevisionBasedModel<TRevision> : IRevisionBasedModel<TRevision>
{
public TRevision Details
{
get { return Revisions.OrderByDescending(x => x.TimeStamp).First();
}
public virtual ICollection<TRevision> Revisions { get; set; }
= new HashSet<TRevision>();
}
public class ModelDetails {
public int Id { get; set; }
public string PropertyOne { get; set; }
public string PropertyTwo { get; set; }
}
视图模型
public class ModelVM {
public int Id { get; set; }
public int RevisionId { get; set; }
public string PropertyOne { get; set; }
public string PropertyTwo { get; set; }
public ICollection<ModelTwoVM> RelationExample { get; set; }
= new HashSet<ModelTwoVM>
}
当前映射配置
CreateMap<Model, ModelVM>()
.ForMember(x => x.RelationExample, opt => opt.MapFrom(y => y.RelationExample));
CreateMap<ModelDetails, ModelVM>()
.ForMember(x => x.RevisionId, opt => opt.MapFrom(y => y.Id));
CreateMap<ModelTwo, ModelTwoVM>();
CreateMap<ModelTwoDetails, ModelTwoVM>()
.ForMember(x => x.RevisionId, opt => opt.MapFrom(y => y.Id));
当前转化
var viewModel = this._mapper.Map<Model, ModelVM>(model);
viewModel = this._mapper.Map<ModelDetails, ModelVM>(model.Details, viewModel);
更新24-01-2017 19:26
在评论中,通过使用自定义类型转换器,建议采用可能的“粗略”方式。我能够使修订部分工作,但由于默认映射被覆盖,我失去了我的关系映射。
public class RevisionConverter<TModel, TRevision, TViewModel> : ITypeConverter<TModel, TViewModel>
where TModel : IRevisionBasedModel<int, TRevision>
{
public TViewModel Convert(TModel source, TViewModel destination, ResolutionContext context)
{
return context.Mapper.Map<TRevision, TViewModel>(source.Details, destination);
}
}