2011-12-01 117 views
2

我在标题中提到的映射有一些问题。下面是详细信息:Automapper映射IList <>到Iesi.Collections.Generic.ISet <>

class MyDomain 
{ 
    public Iesi.Collections.Generic.ISet<SomeType> MySomeTypes{ get; set; } 
    .... 
} 


class MyDTO 
{ 
    public IList<SomeTypeDTO> MySomeTypes{ get; set; } 
    ... 
} 

映射:

Mapper.CreateMap<MyDomain, MyDTO>().ForMember(dto=>dto.MySomeTypes, opt.ResolveUsing<DomaintoDTOMySomeTypesResolver>()); 

Mapper.CreateMap<MyDTO, MyDomain>().ForMember(domain=>domain.MySomeTypes, opt.ResolveUsing<DTOtoDomainMySomeTypesResolver>()); 

解析器:从域名

class DomaintoDTOMySomeTypesResolver: ValueResolver<MyDomain, IList<SomeTypeDTO>> 
{ 
    protected override IList<SomeTypeDTO> ResolveCore(MyDomain source) 
    { 
     IList<SomeTypeDTO> abc = new List<DemandClassConfigurationDTO>(); 
     //Do custom mapping 
     return abc; 
    } 
} 

class DTOtoDomainMySomeTypesResolver: ValueResolver<MyDTO, Iesi.Collections.Generic.ISet<SomeType>> 
{ 
    protected override Iesi.Collections.Generic.ISet<SomeType> ResolveCore(SystemParameterDTO source) 
    { 
    Iesi.Collections.Generic.ISet<SomeType> abc = new HashedSet<SomeType>(); 
    //Do custom mapping 
    return abc; 
    } 
} 

映射到DTO工程确定和预期我得到一个MyDTO对象用的IList “SomeTypeDTO”对象。 然而,DTO映射到域引发以下错误:

Exception of type 'AutoMapper.AutoMapperMappingException' was thrown. 
    ----> AutoMapper.AutoMapperMappingException : Trying to map Iesi.Collections.Generic.HashedSet`1[SomeType, MyAssembly...] to Iesi.Collections.Generic.ISet`1[SomeType, MyAssembly...] 

Exception of type 'AutoMapper.AutoMapperMappingException' was thrown. 
    ----> System.InvalidCastException : Unable to cast object of type 'System.Collections.Generic.List`1[SomeType]' to type 'Iesi.Collections.Generic.ISet`1[SomeType] 

什么可能我是做错了什么和做什么的错误信息意味着什么?似乎automapper在映射ISet(连同其具体实现HashedSet)时遇到了一些问题。我的理解是,在上述场景中,automapper应该只使用由“DTOtoDomainMySomeTypesResolver”返回的ISet引用。我也不明白为什么我得到“从列表转换为ISet错误”。

回答

1

这是因为AutoMapper目前不支持ISet<>集合属性。它在ISet<>的目标属性已经实例化(非空)时起作用,因为ISet<>实际上是从ICollection<>继承的,因此Automapper可以理解并且将正确地执行集合映射。

当destination属性为null并且是接口类型时,它不起作用。你会得到这个错误,因为automapper实际上发现它可以从ICollection<>中分配,所以它使用通用List<>实例化属性,当automapper必须创建新的集合属性时它是默认集合,但是当它试图实际分配它时,它会失败,因为很明显List<>不能转换到ISet<>

有三种解决这个:

  1. 创建一个功能请求,支持ISet<>集合,并希望他们将它添加
  2. 确保属性不为null 。例如。在构造函数中将其实例化为空HashSet<>。这可能会导致ORM层出现一些问题,但是可行
  3. 我最好的解决方案是创建自定义值解析器,您已经拥有该解析器,并且在属性为null的情况下自己实例化属性。您需要实施IValueResolver,因为提供的基地ValueResolver不会让您实例化该属性。这里是代码片段,我用:
​​

然后在你的映射使用opt => opt.ResolveUsing(new EntitCollectionMerge<Entity,Dto>()).FromMember(x => x.ISetMember)或者如果你有很多收集这样的,你可以自动通过typeMaps将它们添加到所有的人。

相关问题