使用automapper将子属性映射到同一模型

时间:2017-01-24 13:49:47

标签: c# asp.net-core asp.net-core-mvc automapper change-tracking

问题

我有一个域模型,其中包含一个修订系统。在概念上它看起来像这样:

Model -> ModelDetails

模型包含与其他对象的所有关系,并且ICollectionModelDetails。它还有一个显示最新版本的details属性。到目前为止,我已经通过手动编码将所有内容映射到视图模型。这些基本上是ModelModelDetails(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);
    }
}

0 个答案:

没有答案