通过AutoMapper映射获取相关数据?

时间:2018-03-31 11:30:41

标签: c# asp.net-core-mvc automapper entity-framework-core

我想在这个实体模型之间创建一个映射:

public class ProductType
{
    public int Id { get; set; }
    public string Title { get; set; }
    public int SortOrder { get; set; }

    public ICollection<ProductIdentifierInType> Identifiers { get; set; }
    public ICollection<ProductPropertyInType> Properties { get; set; }
    public ICollection<Product> Products { get; set; }
}

...和这个viewmodel:

public class ViewModelProductType
{
    public int Id { get; set; }
    public string Title { get; set; }
    public int SortOrder { get; set; }

    public IList<ViewModelProductIdentifier> Identifiers { get; set; }
    public IList<ViewModelProductProperty> Properties { get; set; }
    public ICollection<ViewModelProduct> Products { get; set; }
}

...但由于IdentifiersProperties在视图模型中与实体模型中的类型不同,因此它不会直接工作,如下所示:

CreateMap<ProductType, ViewModelProductType>();

我不想太多改变我的模特。在实体模型中,我需要IdentifiersProperties分别为ProductIdentifierInTypeProductPropertyInType,因为那里存在多对多关系,这需要链接表。

但是在viewmodel中,我需要IdentifiersProperties作为完整对象才能在视图中显示其属性。

有没有办法通过映射实现这一目标?也许使用.ForPath()来获取两个对象&#39;特性

2 个答案:

答案 0 :(得分:2)

假设您已定义直接实体以查看模型映射:

CreateMap<ProductIdentifier, ViewModelProductIdentifier>();
CreateMap<ProductProperty, ViewModelProductProperty>();

现在使用Select表达式中的LINQ MapFrom提取相应的成员就足够了。重要的是要知道AutoMapper不需要返回表达式的类型来匹配目标的类型。如果它们不匹配,AutoMapper将使用该类型的显式或隐式映射。

CreateMap<ProductType, ViewModelProductType>()
    .ForMember(dst => dst.Identifiers, opt => opt.MapFrom(src =>
        src.Identifiers.Select(link => link.Identifier)))
    .ForMember(dst => dst.Properties, opt => opt.MapFrom(src =>
        src.Properties.Select(link => link.Property)))
; 

答案 1 :(得分:1)

我认为你要找的是Custom Value Resolver。 在那里,您可以明确指定Auto Mapper应如何将一个对象映射到另一个对象。

在你的情况下,它看起来像这样:

public class CustomResolver : IValueResolver<ProductType, ViewModelProductType, IList<ViewModelProductIdentifier>>
{
    public int Resolve(ProductType source, ViewModelProductType destination, IList<ViewModelProductIdentifier> destMember, ResolutionContext context)
    {
        // Map you source collection to the destination list here and return it
    }
}

然后,您可以在调用CreateMap时传递/注入解析器,即:

CreateMap<ProductType, ViewModelProductType>()
 .ForMember(dest => dest.Identifiers, opt => opt.ResolveUsing<CustomResolver>());

类似地,对“属性”属性执行相同操作。 请注意,我没有对此进行调试,只是调整了上面链接中提供的示例。

相关问题