我正在尝试将我的一个模型的嵌套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();
答案 0 :(得分:3)
首先,您必须添加CreateMap<IngredientComposition, Composition>();
并在执行此操作后必须更改Linq查询。您可以使用AutoMapper.EF6
return _context.Ingredients
.Where(i => i.CustomerId ==_userResolverService.GetCustomerId())
.Include(i => i.IngredientComposition)
.ProjectToList<IngredientDto>();
使用后你不需要使用Select
。
注意:不要忘记在_mapper.ConfigurationProvider
ProjectToList
ProjectToList<IngredientDto>(_mapper.ConfigurationProvider);
如果你没有将它设置为获得此异常:
Mapper未初始化。使用适当的配置调用Initialize。如果您尝试通过容器或其他方式使用映射器实例,请确保您没有对静态Mapper.Map方法的任何调用,并且如果您使用的是ProjectTo或UseAsDataSource扩展方法,请确保传入适当的IConfigurationProvider实例
更多detail。
更新:您的媒体资源必须具有相同的名称。如果您将Dto属性Ingredients
更改为IngredientComposition
,则无需使用ForMember
。
答案 1 :(得分:1)
实际上这对我有用:
查询:
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();
感谢您的帮助!
答案 2 :(得分:0)
如果您为儿童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()