使用 Automapper - 如何从此 ICollection 进行映射?

Using Automapper - how do I map from this ICollection?

我是第一次使用 entity framework 和自动映射器。我搞不清楚了。我有一个 class 包含另一个 class 的 ICollection 我想映射:

这是我的 classes:

public class BaseEntity {
    public int Id { get; set; }
}

public class Car : BaseEntity {
    public string Make { get; set; }
    public string Model { get; set; }
    public int Year { get; set; }
    public ICollection<CarPart> CarParts { get; set; }
}

public class Part : BaseEntity {
    public string PartName { get; set; }
}

public class CarPart : BaseEntity {
    public int CarId { get; set; }
    public Car Car { get; set; }
    public int PartId { get; set; }
    public Part Part { get; set; }
}

然后是我的 DTO:

public class CarDTO {
    public int Id { get; set; }
    public string Make { get; set; }
    public string Model { get; set; }
    public int Year { get; set; }
    public ICollection<CarPart> CarParts { get; set; }
}

我的映射配置文件包含:

CreateMap<Car, CarDTO> ();

然后在我的控制器中使用:

private readonly IMapper _mapper;
return _mapper.Map<Car, CarDTO>(car);

当我点击 API 时,出现以下错误:

Destination Member:
CarParts
 ---> AutoMapper.AutoMapperMappingException: Missing type map configuration or unsupported mapping.
Mapping types:
CarPart -> Part
Entities.CarPart -> Entities.Part

我需要做哪些更改才能解决此问题? 谢谢。

编辑: 以下全部在StartUp.cs:

public void ConfigureServices(IServiceCollection services)
{
     services.AddAutoMapper(typeof(MappingProfiles));
}

编辑#2: 稍微改变一下这个范围。我将 CarDTO 更改为

public class CarDTO {
    public int CarId { get; set; }
    public string Make { get; set; }
    public string Model { get; set; }
    public int Year { get; set; }
    public IReadOnlyList<Part> Parts { get; set; }
}

并添加了以下 DTO:

 public class PartDTO
    {
        public int PartId { get; set; }
        public string PartName { get; set; }
    }

并将我的映射配置文件编辑为

  public MappingProfiles () {
    
            CreateMap<Car, CarDTO> ()
.ForMember(dest => dest.CarId, opt => opt.MapFrom(src => src.Id))
                .ForMember (dest => dest.Parts, opt =>
                    opt.MapFrom (src => src.CarParts.Select (x => x.Part
                    )));
    
            CreateMap<Part, PartDTO>()
            .ForMember(dest => dest.PartId, opt => opt.MapFrom(src => src.Id))
        }

哪个returns这个:

{
    "carId": 8,
    "make": "some make",
    "model": "some model",
    "year": 2001,
    "parts": [
        {
            "partName": "Fully sick Wheels",
            "id": 3
        },
        {
            "partName": "Mad Engine",
            "id": 4
        }
    ]
}

如何将其更改为:

{
    "carId": 8,
    "make": "some make",
    "model": "some model",
    "year": 2001,
    "parts": [
        {
            "partName": "Fully sick Wheels",
            "partId": 3
        },
        {
            "partName": "Mad Engine",
            "partId": 4
        }
    ]
}

还添加

CreateMap<CarPart, CarPart> ();
CreateMap<Part, Part> ();

应该可以。

CreateMap<Car, CarDTO>().ReverseMap();

更改 CarDTO 中的集合 属性,使其变为 -

public class CarDTO 
{
    public int CarId { get; set; }
    public string Make { get; set; }
    public string Model { get; set; }
    public int Year { get; set; }
    public IReadOnlyList<PartDTO> Parts { get; set; }   // this one
}

只需将其从 IReadOnlyList<Part> 更改为 IReadOnlyList<PartDTO> 即可解决您的问题。

根据您当前对 CarDTO 的定义,您的第一张地图中的以下配置 -

.ForMember (dest => dest.Parts, opt =>
                    opt.MapFrom (src => src.CarParts.Select (x => x.Part)));

基本上是从Part映射到Part

所以您的第二张地图,从 PartPartDTO,根本没有被使用。因此 PartId 没有出现。