【问题标题】:Getting related data via an AutoMapper mapping?通过 AutoMapper 映射获取相关数据?
【发布时间】:2018-09-10 06:02:07
【问题描述】:

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

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; }
}

...还有这个视图模型:

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,因为那里是多对多关系,需要链接表。

但在视图模型中,我需要 IdentifiersProperties 成为完整的对象,以便在视图中显示它们的属性。

有没有办法通过映射来实现这一点?也许使用.ForPath() 来获取两个对象的属性?

【问题讨论】:

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


    【解决方案1】:

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

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

    现在使用 LINQ SelectMapFrom 表达式中提取相应的成员就足够了。重要的是要知道 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)))
    ; 
    

    【讨论】:

    • 是的!谢谢! :D
    【解决方案2】:

    我认为您正在寻找的是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>());
    

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

    【讨论】:

      猜你喜欢
      • 2018-07-14
      • 1970-01-01
      • 1970-01-01
      • 2018-04-13
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      • 2020-03-01
      • 1970-01-01
      相关资源
      最近更新 更多