Automapper,映射一个 属性 是多对多 table
Automapper, map a property that is on the many to many table
我正在开发 .NET 5 API.
我必须回复一个 Json 的 get 调用,它序列化了 UnitDto class 并在其中列出了所有 InstDto class 但我需要一个 属性 驻留在 UnitInst 对象上(table 多对多)
我的class是:
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
}
我的 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
}
我用这种方式映射,没问题,但我无法从 UnitInst class(多对多 table)
中检索 IPv4 属性
CreateMap<Unit, UnitDto>()
.ForMember(dto => dto.Insts, opt => opt.MapFrom(x => x.UnitInsts.Select(y => y.Inst).ToList()))
.PreserveReferences();
我该如何解决?
通常您会创建 2 个地图(Unit
-> UnitDto
和 Inst
-> InstDto
)并使用您使用的 Select
技巧显示。但这仅适用于加入实体没有附加数据的情况,这里不是这种情况。
所以需要直接映射join实体集合:
CreateMap<Unit, UnitDto>()
.ForMember(dst => dst.Insts, opt => opt.MapFrom(src => src.UnitInsts)); // <-- no Select
并创建附加地图 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));
这里AutoMapperIncludeMembers用于映射正则Inst
->InstDTO
映射指定的Inst
成员,目标Id
属性 被显式映射,因为源对象和“包含”对象都有同名的 属性,在这种情况下,源对象具有优先权,但您希望 Id
成为 Inst.Id
或 InstId
.
最后 Inst
-> InstDTO
地图:
CreateMap<Inst, InstDTO>()
.ForMember(dst => dst.IPv4, opt => opt.Ignore());
我正在开发 .NET 5 API.
我必须回复一个 Json 的 get 调用,它序列化了 UnitDto class 并在其中列出了所有 InstDto class 但我需要一个 属性 驻留在 UnitInst 对象上(table 多对多)
我的class是:
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
}
我的 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
}
我用这种方式映射,没问题,但我无法从 UnitInst class(多对多 table)
中检索 IPv4 属性CreateMap<Unit, UnitDto>()
.ForMember(dto => dto.Insts, opt => opt.MapFrom(x => x.UnitInsts.Select(y => y.Inst).ToList()))
.PreserveReferences();
我该如何解决?
通常您会创建 2 个地图(Unit
-> UnitDto
和 Inst
-> InstDto
)并使用您使用的 Select
技巧显示。但这仅适用于加入实体没有附加数据的情况,这里不是这种情况。
所以需要直接映射join实体集合:
CreateMap<Unit, UnitDto>()
.ForMember(dst => dst.Insts, opt => opt.MapFrom(src => src.UnitInsts)); // <-- no Select
并创建附加地图 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));
这里AutoMapperIncludeMembers用于映射正则Inst
->InstDTO
映射指定的Inst
成员,目标Id
属性 被显式映射,因为源对象和“包含”对象都有同名的 属性,在这种情况下,源对象具有优先权,但您希望 Id
成为 Inst.Id
或 InstId
.
最后 Inst
-> InstDTO
地图:
CreateMap<Inst, InstDTO>()
.ForMember(dst => dst.IPv4, opt => opt.Ignore());