C# 使用AutoMapper映射IList<;t来源>;至(Iesi.Collections.Generic)ISet<;TDestination>;

C# 使用AutoMapper映射IList<;t来源>;至(Iesi.Collections.Generic)ISet<;TDestination>;,c#,nhibernate,automapper,C#,Nhibernate,Automapper,我已经试着解决这个问题一天了,但我不知道在哪里,所以我希望有人可能已经解决了这个问题。我找到的最接近解决方案是,但仍然没有快乐 我有一个数据对象,看起来像: public class Parent { public virtual ISet<Child> Children {get; set; } } public class ParentDto { public IList<ChildDto> Children {get; set; } } 公共类父

我已经试着解决这个问题一天了,但我不知道在哪里,所以我希望有人可能已经解决了这个问题。我找到的最接近解决方案是,但仍然没有快乐

我有一个数据对象,看起来像:

public class Parent
{
   public virtual ISet<Child> Children  {get; set; }
}
public class ParentDto
{
   public IList<ChildDto> Children  {get; set; }
}
公共类父类
{
公共虚拟ISet子项{get;set;}
}
以及一个业务对象,看起来像:

public class Parent
{
   public virtual ISet<Child> Children  {get; set; }
}
public class ParentDto
{
   public IList<ChildDto> Children  {get; set; }
}
公共类ParentDto
{
公共IList子项{get;set;}
}
使用AutoMapper将数据映射到业务工作正常:

...
Mapper.CreateMap<Parent, ParentDto>();
Mapper.CreateMap<Child, ChildDto>();
...

ParentDto destination = CWMapper.Map<Parent, ParentDto>(source);
。。。
CreateMap();
CreateMap();
...
ParentDto destination=CWMapper.Map(源);
但当我谈到从业务到数据的映射时,我得到了一个错误:

...
Mapper.CreateMap<ParentDto, Parent>();
Mapper.CreateMap<ChildDto, Child>();
...

Parent destination = CWMapper.Map<ParentDto, Parent>(source);
。。。
CreateMap();
CreateMap();
...
父目的地=CWMapper.Map(源);
无法将“System.Collections.Generic.List”类型的对象强制转换为“Iesi.Collections.Generic.ISet”

我添加了一个自定义映射:

Mapper.CreateMap<ParentDto, Parent>()
      .ForMember(m => m.Children, o => o.MapFrom(s => ToISet<ChildDto>(s.Children)));

private static ISet<T> ToISet<T>(IEnumerable<T> list)
    {
        Iesi.Collections.Generic.ISet<T> set = null;

        if (list != null)
        {
            set = new Iesi.Collections.Generic.HashedSet<T>();

            foreach (T item in list)
            {
                set.Add(item);
            }
        }

        return set;
    }
Mapper.CreateMap()
.ForMember(m=>m.Children,o=>o.MapFrom(s=>ToISet(s.Children));
专用静态ISet集合(IEnumerable列表)
{
Iesi.Collections.Generic.ISet set=null;
如果(列表!=null)
{
set=新的Iesi.Collections.Generic.HashedSet();
foreach(列表中的T项)
{
设置。添加(项目);
}
}
返回集;
}

但我还是犯了同样的错误。任何帮助都是非常必要的

这是因为要映射的源和目标属性中的源和目标泛型类型参数不同。您需要的映射是从
IEnumerable
ISet
,可以概括为从
IEnumerable
ISet
的映射,而不是从
IEnumerable
ISet
。您需要在转换函数中考虑到这一点(实际上,您的问题标题中有正确的答案…)

ToISet方法应该与下面发布的方法类似。它还使用AutoMapper将
ChildDto映射到
Child

private static ISet<TDestination> ToISet<TSource, TDestination>(IEnumerable<TSource> source)
{
    ISet<TDestination> set = null;
    if (source != null)
    {
        set = new HashSet<TDestination>();

        foreach (TSource item in source)
        {
            set.Add(Mapper.Map<TSource, TDestination>(item));
        }
    }
    return set;
}
私有静态ISet集合(IEnumerable源代码)
{
ISet集合=空;
如果(源!=null)
{
set=新的HashSet();
foreach(源中的TSource项)
{
set.Add(Mapper.Map(item));
}
}
返回集;
}
然后可以按如下方式更改贴图定义:

Mapper.CreateMap<ParentDto, Parent>().ForMember(m => m.Children,
          o => o.MapFrom(p => ToISet<ChildDto, Child>(p.Children)));
Mapper.CreateMap().ForMember(m=>m.Children,
o=>o.MapFrom(p=>ToISet(p.Children));
您可以使用AutoMapper的AfterMap()函数,如下所示:

Mapper.CreateMap<ParentDto, Parent>()
      .ForMember(m => m.Children, o => o.Ignore()) // To avoid automapping attempt
      .AfterMap((p,o) => { o.Children = ToISet<ChildDto, Child>(p.Children); });
Mapper.CreateMap()
.ForMember(m=>m.Children,o=>o.Ignore())//以避免自动映射尝试
.AfterMap((p,o)=>{o.Children=ToISet(p.Children);});
AfterMap()允许对NHibernate子集合处理的一些重要方面进行更细粒度的控制(如替换现有集合内容,而不是像此简化示例中那样覆盖集合引用)。

Mapper.CreateMap().ConstructUsing(c=>ToSet(c));也不行。