简体   繁体   English

Automapper,map 一个位于多对多表上的属性

[英]Automapper, map a property that is on the many to many table

I'm working on an .NET 5 API .我正在研究.NET 5 API

I have to reply to a get call with a Json that serializes the UnitDto class and inside it the list of all the InstDto class but I need a property that resides on the UnitInst object (the table many to many) I have to reply to a get call with a Json that serializes the UnitDto class and inside it the list of all the InstDto class but I need a property that resides on the UnitInst object (the table many to many)

My classes:我的课程:

public class Unit
{
    public long Id { get; set; }
    public string Name { get; set; }
    public string Description { get; set; }

    public virtual ICollection<UnitInst> UnitInsts { get; set; }
}

public class Inst
{
    public long Id { get; set; }
    public string Name { get; set; }

    public virtual ICollection<UnitInst> UnitInsts { get; set; }
}

public class UnitInst
{
    public long Id { get; set; }
    public long UnitId { get; set; }
    public virtual Unit Unit { get; set; }
    public long InstId { get; set; }
    public virtual Inst Inst { get; set; }
    public string IPv4 { get; set; } // the property that is important
}

My dto's我的dto

public class UnitDto
{
    public long Id { get; set; }
    public string Name { get; set; }
    public string Description { get; set; }

    public IEnumerable<InstDTO> Insts { get; set; }
}

public class InstDTO
{
    public long Id { get; set; }
    public string Name { get; set; }
    public string IPv4 { get; set; } // I need serialize this property in my response json
}

I map in this way and it's ok but i can't retrive IPv4 property from UnitInst class (the many to many table)我以这种方式 map 没关系,但我无法从 UnitInst class (多对多表)中检索 IPv4 属性

CreateMap<Unit, UnitDto>()
    .ForMember(dto => dto.Insts, opt => opt.MapFrom(x => x.UnitInsts.Select(y => y.Inst).ToList()))
    .PreserveReferences();

How can I solve?我该如何解决?

Normally you would create 2 maps ( Unit -> UnitDto and Inst -> InstDto ) and use the Select trick you've shown.通常您会创建 2 个地图( Unit -> UnitDtoInst -> InstDto )并使用您展示的Select技巧。 But that is applicable only when the join entity has no additional data, which is not the case here.但这仅适用于连接实体没有附加数据的情况,此处并非如此。

So you need to map the join entity collection directly:所以需要 map 直接加入实体集合:

CreateMap<Unit, UnitDto>()
    .ForMember(dst => dst.Insts, opt => opt.MapFrom(src => src.UnitInsts)); // <-- no Select

and create additional map UnitInst -> InstDto :并创建额外的 map UnitInst -> InstDto

cfg.CreateMap<UnitInst, InstDTO>()
    .IncludeMembers(src => src.Inst) // needs `Inst` -> `InstDTO` map
    .ForMember(dst => dst.Id, opt => opt.MapFrom(src => src.Inst.Id));

Here AutoMapper IncludeMembers is used to map the Inst members specified by the regular Inst -> InstDTO map, and the target Id property is mapped explicitly because both source and "included" objects have a property with the same name, in which case the source have priority, but you want Id to be Inst.Id or InstId .这里 AutoMapper IncludeMembers用于 map 由常规Inst -> InstDTO map 指定的Inst成员,并且目标Id属性被显式映射,因为源和“包含”对象具有同名的属性,在这种情况下源具有优先级,但您希望IdInst.IdInstId

Finally the Inst -> InstDTO map:最后是Inst -> InstDTO map:

CreateMap<Inst, InstDTO>()
    .ForMember(dst => dst.IPv4, opt => opt.Ignore());

声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM