【问题标题】:AutoMapper mapping ICollection with EFAutoMapper 使用 EF 映射 ICollection
【发布时间】:2017-08-21 18:00:56
【问题描述】:

我正在尝试将我的一个模型的嵌套 ICollection 映射到现有 Dto,但我正在努力使用 AutoMapper 正确映射它

型号:

public class Ingredient : BaseEntity<long>
{
    [MaxLength(100)]
    public string Name { get; set; }
    [ForeignKey("Id")]
    public int CustomerId { get; set; }
    public bool IsPackaging { get; set; }
    public virtual ICollection<ProductIngredient> ProductIngredient { get; set; }
    public virtual ICollection<IngredientComposition> IngredientComposition { get; set; }
}

收藏模型:

public class IngredientComposition : BaseEntity<int>
{
    [MaxLength(20)]
    public string Type { get; set; }
    [MaxLength(200)]
    public string Key { get; set; }
    [MaxLength(200)]
    public string Value { get; set; }
}

Dto:

public class IngredientDto
{
    public long Id { get; set; }
    public DateTime CretedOn { get; set; }
    public DateTime UpdatedOn { get; set; }
    public string Name { get; set; }
    public int CustomerId { get; set; }
    public int UsedCount { get; set; }
    public bool IsPackaging { get; set; }
    public IList<Composition> Ingredients { get; set; }
}

public class Composition
{
    public string Type { get; set; }
    public string Key { get; set; }
    public string Value { get; set; }
}

当我努力正确设置“ForMemeber”方法时,我的地图如下所示:

CreateMap<Ingredient, IngredientDto>();
CreateMap<IngredientDto, Ingredient>();

任何帮助都非常合适! 谢谢

编辑:

这就是我获取数据的方式:

return await _context.Ingredients
                     .Where(i => i.CustomerId ==_userResolverService.GetCustomerId())
                     .Include(i => i.IngredientComposition)
                     .Select(i => _mapper.Map<Ingredient, IngredientDto>(i))
                     .OrderBy(i => i.Name)
                     .ToListAsync();

【问题讨论】:

  • 添加 CreateMap&lt;IngredientComposition, Composition&gt;(); 并重试。
  • 您好,不幸的是,这不起作用。我仍然在 IngredientDto 上得到 null 而不是数组,但成分已附加集合 - 看看编辑我如何获取数据

标签: c# entity-framework .net-core automapper


【解决方案1】:

首先,您必须添加 CreateMap&lt;IngredientComposition, Composition&gt;();,然后您必须更改您的 Linq 查询。你可以使用AutoMapper.EF6

return _context.Ingredients
                 .Where(i => i.CustomerId ==_userResolverService.GetCustomerId())
                 .Include(i => i.IngredientComposition)
                 .ProjectToList<IngredientDto>();

使用后你不需要使用Select。

注意:不要忘记在ProjectToList中添加_mapper.ConfigurationProvider

ProjectToList<IngredientDto>(_mapper.ConfigurationProvider);

如果你没有设置它来获取这个异常:

映射器未初始化。使用适当的配置调用初始化。如果您尝试通过容器或其他方式使用映射器实例,请确保您没有对静态 Mapper.Map 方法的任何调用,并且如果您使用 ProjectTo 或 UseAsDataSource 扩展方法,请确保传入适当的 IConfigurationProvider实例。

更多detail.

更新:您的属性必须具有相同的名称。如果您将 Dto 属性 Ingredients 更改为 IngredientComposition,则不需要使用 ForMember。

【讨论】:

  • 不需要包含,默认情况下 AM 获取所有内容。
  • 是的,也许@sziszu 确实使用了急切加载。
  • 奇怪,它仍然返回 null。这可能是因为它是.net核心吗?我也没有 ProjectToList,所以我这样做了: return await _context.Ingredients.Where(i => i.CustomerId == _userResolverService.GetCustomerId()) .ProjectTo(_mapper.ConfigurationProvider).ToListAsync() ;
【解决方案2】:

实际上这对我有用:

查询:

return await _context.Ingredients.Where(i => i.CustomerId == _userResolverService.GetCustomerId())
        .Include(sx=>sx.IngredientComposition)
        .ProjectTo<IngredientDto>()
        .ToListAsync();

地图: 首先,正如您所建议的那样,内部集合映射,然后是主对象映射 + ForMember,一旦内部对象被映射,它就会起作用

CreateMap<IngredientComposition, Composition>().ReverseMap();
CreateMap<Ingredient, IngredientDto>().ForMember(d => d.Ingredients, opt=>opt.MapFrom(c=>c.IngredientComposition)).ReverseMap();

感谢大家的帮助!

【讨论】:

  • 糟糕,是的,我认为您的属性具有相同的名称。如果您将 Dto 属性 Ingredients 更改为 IngredientComposition,则不需要使用 ForMember。
  • 是的@Soheil Alizadeh 你是对的,一旦改变它也可以工作,我会修改答案以包含这些信息
  • 如果我的回答是正确的,请接受,谢谢,@sziszu。
【解决方案3】:

如果您为子 DTO 制作地图,Automapper 足够聪明,可以在没有 ForMember 的情况下找出它:

CreateMap<IngredientComposition , Composition>()
    .ReverseMap();  //Reverse map tells AM to go both ways

CreateMap<Ingredient, IngredientDto>()
    .ReverseMap();

// CreateMap<IngredientDto, Ingredient>();  ** Not needed with ReverseMap()

【讨论】:

  • 您好,不幸的是,这不起作用。我仍然在 IngredientDto 上得到 null 而不是数组,但成分已附加集合 - 看看编辑我如何获取数据
猜你喜欢
  • 1970-01-01
  • 2022-01-04
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
相关资源
最近更新 更多