使用AutoMapper将IList 映射到(Iesi.Collections.Generic)ISet
我一直试图解决这个问题一天,没有在哪里,所以我希望有人可能已经解决了这个问题。 我发现最接近解决方案的是如何使用AutoMapper简单地将NHibernate ISet映射到IList并通过AutoMapper 将IList 映射到ICollection但仍然没有乐趣。
我有一个数据对象,看起来像:
public class Parent { public virtual ISet Children {get; set; } }
以及如下所示的业务对象:
public class ParentDto { public IList Children {get; set; } }
使用AutoMapper从数据映射到业务工作正常:
... Mapper.CreateMap(); Mapper.CreateMap(); ... ParentDto destination = CWMapper.Map(source);
但是,当我从业务映射到数据时,我得到错误:
... Mapper.CreateMap(); Mapper.CreateMap(); ... Parent destination = CWMapper.Map(source);
无法将’System.Collections.Generic.List’类型的对象强制转换为”Iesi.Collections.Generic.ISet’
我添加了一个自定义映射:
Mapper.CreateMap() .ForMember(m => m.Children, o => o.MapFrom(s => ToISet(s.Children))); private static ISet ToISet(IEnumerable list) { Iesi.Collections.Generic.ISet set = null; if (list != null) { set = new Iesi.Collections.Generic.HashedSet(); foreach (T item in list) { set.Add(item); } } return set; }
但我仍然得到同样的错误。 任何帮助都会受到极大的关注!
这是因为源映射和目标generics类型参数在您映射的源和目标属性中不相同。 您需要的映射是从IEnumerable
到ISet
,它可以推广到从IEnumerable
到ISet
的映射,而不是IEnumerable
到ISet
。 您需要在转换function中考虑到这一点(实际上您在问题的标题中有正确的答案……)。
ToISet方法应该类似于下面发布的方法。 它还使用AutoMapper将ChildDto
映射到Child
。
private static ISet ToISet(IEnumerable source) { ISet set = null; if (source != null) { set = new HashSet (); foreach (TSource item in source) { set.Add(Mapper.Map(item)); } } return set; }
然后,您可以按如下方式更改地图定义:
Mapper.CreateMap().ForMember(m => m.Children, o => o.MapFrom(p => ToISet(p.Children)));
您可以使用AutoMapper的AfterMap()函数,如下所示:
Mapper.CreateMap() .ForMember(m => m.Children, o => o.Ignore()) // To avoid automapping attempt .AfterMap((p,o) => { o.Children = ToISet(p.Children); });
AfterMap()允许对NHibernate子集合处理的一些重要方面进行更细粒度的控制(如替换现有集合内容而不是覆盖集合引用,如此简化示例)。