首页 > 解决方案 > 内含集合的地图模型

问题描述

我有一个类似这样的 API 端点:

        [HttpGet("{shoppingCartId}")]
        public async Task<IActionResult> GetShoppingCart(int shoppingCartId)
        {
            var shoppingCart = await context.ShoppingCarts.Include(c => c.ShoppingCartItems).SingleOrDefaultAsync(c => c.Id == shoppingCartId);

            if (shoppingCart == null)
                return NotFound("There is no shoppingCart for specified query.");

            return Ok(shoppingCart);
        }

它工作正常。按预期返回带有 ShoppingCartItems 的 ShoppingCart。

但是,我不想返回 shoppingCart 而是 shoppingCartResource。像这样的东西:

        [HttpGet("{shoppingCartId}")]
        public async Task<IActionResult> GetShoppingCart(int shoppingCartId)
        {
            var shoppingCart = await context.ShoppingCarts.Include(c => c.ShoppingCartItems).SingleOrDefaultAsync(c => c.Id == shoppingCartId);

        if (shoppingCart == null)
            return NotFound("There is no shoppingCart for specified query.");

        var shoppingCartResource = mapper.Map<ShoppingCart, ShoppingCartResource>(shoppingCart);
        return Ok(shoppingCartResource);
    }

如您所见, ShoppingCart 模型内部有一个 ShoppingCartItem 集合。

    public class ShoppingCart
    {
        public int Id { get; set; }
        public DateTime DateCreated { get; set; }
        public ICollection<ShoppingCartItem> ShoppingCartItems { get; set; }

        public ShoppingCart()
        {
            ShoppingCartItems = new Collection<ShoppingCartItem>();
        }
    }

这是 ShoppingCartResource 模型

  public class ShoppingCartResource
    {
        public int Id { get; set; }
        public DateTime DateCreated { get; set; }
        public ICollection<ShoppingCartItemResource> ShoppingCartItemResources { get; set; }

        public ShoppingCartResource()
        {
            ShoppingCartItemResources = new Collection<ShoppingCartItemResource>();
        }
    }

映射代码为:

 CreateMap<ShoppingCart, ShoppingCartResource>();
 CreateMap<ShoppingCartItem, ShoppingCartItemResource>();

没有错误,但我得到了唯一一个 ShoppingCartResource 为空的 ShoppingCartItemResource。

标签: c#entity-framework-coreautomapper

解决方案


默认情况下,AutoMapper 遵循一个命名约定,如果它们的名称匹配,它会自动在源属性和目标属性之间创建一个映射,您不必为此进行任何配置。但是,如果您想要两个属性之间的映射并且它们的名称不匹配,那么您必须明确定义该映射的配置。

您的ShoppingCartResourceShoppingCart对象都有名为Idand的属性DateCreated,因此它们会自动映射。

要获取您的ICollection属性之间的地图 -

  1. 如果你想要一个自动地图,你必须给他们一个匹配的名字
  2. 如果要在命名上保持区别,则必须为它们的映射显式定义配置。就像是 -
CreateMap<ShoppingCart, ShoppingCartResource>()
    .ForMember(d => d.ShoppingCartItemResources, opt => opt.MapFrom(s => s.ShoppingCartItems));

CreateMap<ShoppingCartItem, ShoppingCartItemResource>();

推荐阅读