我正在使用 AutoMapper 在 ASP.NET Core Web API 中的不同实体之间进行映射。但是,它没有显示结果,但如果我手动进行映射,它就会起作用 - 我想知道为什么会这样。
我有实体
Order
和 OrderProduct
作为中间表来连接 Order
和 Product
之间的多对多关系。
我为 (
Order, OrderProduct, Product
) 创建了一个 DTO 并为它们做了映射配置文件。
public class Order
{
public Order()
{
OrderDate = DateTime.Now;
}
public int Id { get; set; }
public DateTime OrderDate { get; set; }
public AppUser AppUser { get; set; }
public ICollection<OrderProduct> OrderProducts { get; set; } = new HashSet<OrderProduct>()
}
public class OrderProduct
{
public int Id { get; set; }
public int OrderId { get; set; }
public Order Order { get; set; }
public int ProductId { get; set; }
public Product Product { get; set; }
}
public class Product
{
public int Id { get; set; }
[Required, MaxLength(150)]
public string PName { get; set; }
[Required, MaxLength(250)]
public string PDescription { get; set; }
public decimal Price { get; set; }
}
这是 DTO:
public class OrderDTO
{
public int OrderId { get; set; }
public DateTime OrderDate { get; set; }
public string ProductName { get; set; }
public List<OrderProductDTO> OrderProductDTO { get; set; } = new List<OrderProductDTO>();
}
public class OrderProductDTO
{
public int OrderId { get; set; }
public ProductDTO Products { get; set; }
public int ProductId { get; set; }
public string ProductName { get; set; }
public decimal Price { get; set; }
public int Quantity { get; set; }
}
public class ProductDTO
{
public int productID { get; set; }
public string productName { get; set; }
public decimal productPrice { get; set; }
public int productRating { get; set; }
public string productImageURL { get; set; }
}
// MAPPING Profile
CreateMap<Order, OrderDTO>()
.ForMember(dest => dest.OrderId, opt => opt.MapFrom(src => src.Id))
.ReverseMap();
CreateMap<OrderProduct, OrderProductDTO>()
.ForMember(dest => dest.ProductName, opt => opt.MapFrom(src => src.Product.PName))
.ForMember(dest => dest.OrderId , opt => opt.MapFrom(src => src.OrderId))
.ForMember(dest => dest.ProductId, opt => opt.MapFrom(src => src.Product.Id))
.ReverseMap();
CreateMap<Product, ProductDTO>()
.ForMember(dsc => dsc.productID, src => src.MapFrom(src => src.Id))
.ForMember(dsc => dsc.productName, src => src.MapFrom(src => src.PName))
.ForMember(dsc => dsc.productPrice, src => src.MapFrom(src => src.Price))
.ForMember(dsc => dsc.productImageURL, src => src.MapFrom(src => src.ImageUrl))
.ForMember(dsc => dsc.productRating, src => src.MapFrom(src => src.Rate))
.ReverseMap();
订单控制器(我正在使用存储库模式)
public async Task<IReadOnlyList<Order>> GetOrdersByUsernameAsync(string username)
{
return await _context.Set<Order>()
// .Include(o => o.AppUser)
.Include(o => o.OrderProducts)
.ThenInclude(op => op.Product)
.Where(o => o.AppUser.Id == username)
.ToListAsync();
}
[HttpGet("{userID}")]
public async Task<IActionResult> GetOrdersByUserId(string userID)
{
var orders = await unitOfWork.Orders.GetOrdersByUsernameAsync(userID);
if (orders == null)
{
return BadRequest($"There is no order yet or not found..");
}
// var result = _mapper.Map<IEnumerable<OrderDTO>>(orders);
// return Ok(orders);
// return Ok(result);
var orderDTOs = new List<OrderDTO>();
foreach (var order in orders)
{
var orderDTO = new OrderDTO
{
OrderId = order.Id,
OrderProductDTO = new List<OrderProductDTO>()
};
foreach (var orderProduct in order.OrderProducts)
{
var orderProductDTO = new OrderProductDTO
{
ProductId = orderProduct.ProductId,
ProductName = orderProduct.Product.PName, // manual mapping to product name
Price = orderProduct.Product.Price,
Quantity = orderProduct.Product.Quantity,
};
orderDTO.OrderProductDTO.Add(orderProductDTO);
}
orderDTOs.Add(orderDTO);
}
return Ok(orderDTOs);
}
未映射的退回订单
[
{
"id": 1017,
"orderDate": "2023-04-13T21:38:19.2123593",
"status": 0,
"appUser": null,
"orderProducts": [
{
"id": 0,
"orderId": 1017,
"productId": 1,
"product": {
"id": 1,
"pName": "Nike Men Running Shoes Revolution 5",
"pDescription": "Shoes",
"price": 2000,
"quantity": 50
}
},
{
"id": 0,
"orderId": 1017,
"productId": 2,
"product": {
"id": 2,
"pName": "Supernova",
"pDescription": "Shoes",
"price": 2200,
"quantity": 50
}
}
]
}
]
手动测绘;
[
{
"orderId": 1017,
"orderDate": "0001-01-01T00:00:00",
"productName": null,
"orderProductDTO": [
{
"orderId": 0,
"products": null,
"productId": 1,
"productName": "Nike Men Running Shoes Revolution 5",
"price": 2000,
"quantity": 50
},
{
"orderId": 0,
"products": null,
"productId": 2,
"productName": "Supernova",
"price": 2200,
"quantity": 50
}
]
}
]
使用AutoMapper自动映射:
[
{
"orderId": 1017,
"orderDate": "2023-04-13T21:38:19.2123593",
"productName": null,
"orderProductDTO": [] // Why is not Mapping Right?
}
]
即使使用 AutoMapper,我也期待映射结果...
我修改了您的代码,以提高答案本身的可读性。
正如@Drewskis提到的,您需要重命名OrderDTO中的字段。
还有 OrderProductDTO 中的另一个。
订购
public class Order
{
public Order()
{
OrderDate = DateTime.Now;
}
public int Id { get; set; }
public DateTime OrderDate { get; set; }
public AppUser AppUser { get; set; }
public ICollection<OrderProduct> OrderProducts { get; set; } = new HashSet<OrderProduct>()
}
public class OrderDTO
{
public int OrderId { get; set; }
public DateTime OrderDate { get; set; }
public string ProductName { get; set; }
public List<OrderProductDTO> OrderProducts { get; set; } = new List<OrderProductDTO>(); // Renamed from OrderProductDTO
}
CreateMap<Order, OrderDTO>()
.ForMember(dest => dest.OrderId, opt => opt.MapFrom(src => src.Id))
.ReverseMap();
订购产品
public class OrderProduct
{
public int Id { get; set; }
public int OrderId { get; set; }
public Order Order { get; set; }
public int ProductId { get; set; }
public Product Product { get; set; }
}
public class OrderProductDTO
{
public int OrderId { get; set; }
public ProductDTO Product { get; set; } // Renamed from Products
public int ProductId { get; set; }
public string ProductName { get; set; }
public decimal Price { get; set; }
public int Quantity { get; set; }
}
CreateMap<OrderProduct, OrderProductDTO>()
.ForMember(dest => dest.ProductName, opt => opt.MapFrom(src => src.Product.PName))
.ForMember(dest => dest.OrderId , opt => opt.MapFrom(src => src.OrderId))
.ForMember(dest => dest.ProductId, opt => opt.MapFrom(src => src.Product.Id))
.ReverseMap();
产品
public class Product
{
public int Id { get; set; }
[Required, MaxLength(150)]
public string PName { get; set; }
[Required, MaxLength(250)]
public string PDescription { get; set; }
public decimal Price { get; set; }
}
public class ProductDTO
{
public int productID { get; set; }
public string productName { get; set; }
public decimal productPrice { get; set; }
public int productRating { get; set; }
public string productImageURL { get; set; }
}
CreateMap<Product, ProductDTO>()
.ForMember(dsc => dsc.productID, src => src.MapFrom(src => src.Id))
.ForMember(dsc => dsc.productName, src => src.MapFrom(src => src.PName))
.ForMember(dsc => dsc.productPrice, src => src.MapFrom(src => src.Price))
.ForMember(dsc => dsc.productImageURL, src => src.MapFrom(src => src.ImageUrl))
.ForMember(dsc => dsc.productRating, src => src.MapFrom(src => src.Rate))
.ReverseMap();