Automapper,映射多对多表上的属性

问题描述

我正在开发 .NET 5 API

我必须使用 Json 回复 get 调用,该 Json 序列化了 UnitDto 类并在其中包含所有 InstDto 类的列表,但我需要一个驻留的属性UnitInst 对象(多对多表)

我的课程:

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 类(多对多表)中检索 IPv4 属性

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

我该如何解决?

解决方法

通常您会创建 2 个地图(Unit -> UnitDtoInst -> 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));

这里使用AutoMapper IncludeMembers来映射正则Inst-> Inst映射指定的InstDTO成员,映射目标Id属性明确是因为源和“包含”对象都有一个同名的属性,在这种情况下源具有优先级,但您希望 IdInst.IdInstId

最后是 Inst -> InstDTO 地图:

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

相关问答

依赖报错 idea导入项目后依赖报错,解决方案:https://blog....
错误1:代码生成器依赖和mybatis依赖冲突 启动项目时报错如下...
错误1:gradle项目控制台输出为乱码 # 解决方案:https://bl...
错误还原:在查询的过程中,传入的workType为0时,该条件不起...
报错如下,gcc版本太低 ^ server.c:5346:31: 错误:‘struct...