使用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类型参数在您映射的源和目标属性中不相同。 您需要的映射是从IEnumerableISet ,它可以推广到从IEnumerableISet的映射,而不是IEnumerableISet 。 您需要在转换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子集合处理的一些重要方面进行更细粒度的控制(如替换现有集合内容而不是覆盖集合引用,如此简化示例)。