【发布时间】:2016-03-31 21:40:12
【问题描述】:
我已经查看了很多与此问题相关的 SO 文章,并使用其中一些问题/答案来接近我的情况的答案,但我不能完全正确。
我有一个 EF6 上下文,其中包含 5 个表(Grandparent、GrandparentParent、Parent、ParentChild 和 Child)。 GP 和 PC 表是简单的多对多关系,将家族层次结构联系在一起。
我的业务需求是查询数据库并返回祖父对象列表,其中包含所有孙子对象的列表,而孙子对象不嵌套在父对象之下。我有 3 个 ViewModel 类,它们是它们相应表的子集,我想将数据库层次结构扁平化为 GVM =
的 GrandparentViewModel 类列表public class GrandparentViewModel
{
public int GrandparentId { get; set; }
public string Name { get; set; }
public List<ChildViewModel> Grandchildren { get; set; }
}
还需要注意的是,我在查询中使用了 AutoMapper 的 ProjectTo 扩展方法,因此我可以卸载投影并仅从每个表中选择字段的子集......即......我有 DateOfBirth每个表,我不想查询和/或返回该字段。
在我试图让这个工作正常的过程中,我偶然发现了 AutoMapper 的 ITypeConverter 接口,并构建了一个为祖父母和孩子实现该接口的类。以下是这些类:
public class GrandparentConverter : ITypeConverter<Grandparent, GrandparentViewModel>
{
public GrandparentViewModel Convert(ResolutionContext context)
{
var entities = context.SourceValue as Grandparent;
return entities
.Select(x => new GrandparentViewModel
{
GrandparentId = x.GrandparentId,
Name = x.Name,
Grandchildren = AutoMapper.Mapper.Map<IEnumerable<Parent>, List<ChildViewModel>>(x.Parents)
}).ToList();
//return new GrandparentViewModel
//{
// GrandparentId = entities.GrandparentId,
// Name = entities.Name,
// Grandchildren = entities.Parents.SelectMany(x => x.Children.Select(y => new ChildViewModel
// {
// ChildId = y.ChildId,
// Name = y.Name
// }).ToList()).ToList()
//};
}
}
public class ChildConverter : ITypeConverter<IEnumerable<Parent>, List<ChildViewModel>>
{
public List<ChildViewModel> Convert(ResolutionContext context)
{
var entities = context.SourceValue as IEnumerable<Parent>;
return entities
.SelectMany(x => x.Children)
.Select(x => new ChildViewModel
{
ChildId = x.ChildId,
Name = x.Name
}).ToList();
}
}
这是消费代码:
MapperConfiguration mapper = new MapperConfiguration(cfg =>
{
cfg.CreateMap<Child, ChildViewModel>();
cfg.CreateMap<IEnumerable<Parent>, List<ChildViewModel>>().ConvertUsing<ChildConverter>();
cfg.CreateMap<Grandparent, GrandparentViewModel>();
cfg.CreateMap<IEnumerable<Grandparent>, List<GrandparentViewModel>>().ConvertUsing<GrandparentConverter>();
});
FamilyEntities db = new FamilyEntities();
List<GrandparentViewModel> entities = db.Set<Grandparent>()
.Where(x => x.GrandparentId == 1)
.ProjectTo<GrandparentViewModel>(mapper)
.ToList();
目前,解决方案构建、运行并返回一个单一的 GrandparentViewModel 类,如我所料,但所有字段(包括祖父母...即...名称上的字段)都是空的。
关于我缺少什么和/或为什么没有填充数据的任何想法?我尝试在该 TypeConverter 类中设置断点,但即使 AutoMapper 的 MapperConfiguration 类中指定的唯一映射配置正在使用该转换器,它也不会执行。如果我删除该 CreateMap 调用,AutoMapper 会抛出其“缺少配置”错误。
非常感谢任何建议。
编辑:我构建了这个问题的缩小版本,当我不构建 AutoMapper MapperConfiguration 并将其传递给 ProjectTo 方法时,自定义 TypeConverter 类中的断点被命中。因此,在我原来的帖子中,问题似乎是 AutoMapper 实际上并没有使用 ConvertUsing 方法中指定的转换器。
【问题讨论】:
标签: linq automapper projection