Using AutoMapper to Map IList<TSource> to (Iesi.Collections.Generic) ISet<TDestination>

匿名 (未验证) 提交于 2019-12-03 02:06:01

问题:

I have been trying to solve this issue for a day now and have got no where so am hoping someone might have solved this before. The closest I found to a solution was How to simply map an NHibernate ISet to IList using AutoMapper and Map IList to ICollection through AutoMapper but still no joy.

I have a data object that looks like:

public class Parent {    public virtual ISet Children  {get; set; } }

And a business object that looks like:

public class ParentDto {    public IList Children  {get; set; } }

Using AutoMapper to map from Data to Business works fine:

... Mapper.CreateMap(); Mapper.CreateMap(); ...  ParentDto destination = CWMapper.Map(source);

But when I come to Mapping from Business to Data I get the error:

... Mapper.CreateMap(); Mapper.CreateMap(); ...  Parent destination = CWMapper.Map(source);

Unable to cast object of type 'System.Collections.Generic.List' to ''Iesi.Collections.Generic.ISet'

I added a custom mapping:

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;     }

But I still get the same error. Any help would be greatly apriciated!

回答1:

This is because the source and destination generic type parameters are not the same in the source and target properties that you are mapping. The mapping you need is from IEnumerable to ISet, which can be generalized to a mapping from IEnumerable to ISet and not IEnumerable to ISet. You need to take this into account in your conversion function (actually you have the correct answer in the title of your question..).

The ToISet method should be something like the one posted below. It uses AutoMapper as well to map ChildDto to 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; }

You can then change the map definition as follows:

Mapper.CreateMap().ForMember(m => m.Children,           o => o.MapFrom(p => ToISet(p.Children)));


回答2:

You can use the AfterMap() function of AutoMapper, like this:

Mapper.CreateMap()       .ForMember(m => m.Children, o => o.Ignore()) // To avoid automapping attempt       .AfterMap((p,o) => { o.Children = ToISet(p.Children); });

AfterMap() allows for more fine-grained control of some important aspects of NHibernate child collections handling (like replacing existing collections content instead of overwriting the collections reference as in this simplified example).



标签
易学教程内所有资源均来自网络或用户发布的内容,如有违反法律规定的内容欢迎反馈
该文章没有解决你所遇到的问题?点击提问,说说你的问题,让更多的人一起探讨吧!