Automapper在将泛型IEnumerable映射到泛型List时失败

本文关键字:泛型 List 失败 IEnumerable Automapper 映射 | 更新日期: 2023-09-27 18:08:47

我确实在SO + google中搜索了提到的问题,我经历了所有SO问题,但没有得到我问题的解决方案。

这是我的问题:我得到AutoMapper。尝试映射IEnumerable prop与List prop.

下面是代码片段:

//Logical
public class TestClassPLogical
{
    public List<TestClassLogical> TestProp
    {
        get;
        set;
    }
}
public class TestClassLogical
{
    //defined prop
}
//Model
public class TestClassPDto
{
    public virtual IEnumerable<TestClassDto> TestProp
    {
        get;
        set;
    }
}
public class TestClassDto
{
    //defined prop
}
//Mapping
public class TestClassMapper
{
    public static void Configure()
    {
        //ToDto
        Mapper.CreateMap<TestClassPDto, TestClassPLogical>()
             .ForMember(d => d.TestProp,
             o => o.MapFrom(s => AutoMapperExtensions.MapIEnumerableToList(s.TestProp)));
        //ToLogical
        Mapper.CreateMap<TestClassPLogical, TestClassPDto>()
            .ForMember(d => d.TestProp, o => o.MapFrom(s => AutoMapperExtensions.MapListToIEnumerable(s.TestProp)));
    }
}
//Custom class
public class CustomMapperExtensions
{
    public static List<T> MapIEnumerableToList<T>(IEnumerable<T> source) where T : class
    {
        return source == null
            ? new List<T>()
            : source.ToList();
    }
    public static IEnumerable<T> MapListToIEnumerable<T>(List<T> source) where T : class
    {
        return source.Count > 0
            ? source.ToList()
            : new List<T>();
    }
}
//Unit Test
public class TestClassMapperTest
{
    [TestFixtureSetUp]
    public void Setup()
    {
        TestClassMapper.Configure();
    }
    [Test]
    public void EnsureFieldsAreAllMappedOrIgnored()
    {
        Mapper.AssertConfigurationIsValid();
    }
}

注::我们使用Fluent Nhibernate作为ORM。

以下是例外:

AutoMapper。AutoMapperConfigurationException:以下属性TestProp

任何有助于解决上述问题的人都将不胜感激。

我已经尝试过使用ReverseMap(),它抛出了相同的异常,下面是代码片段:

//Mapping
public class TestClassMapper
{
    public static void Configure()
    {
        //ToDto
        Mapper.CreateMap<TestClassPDto, TestClassPLogical>()
             .ForMember(d => d.TestProp,
             o => o.MapFrom(s => AutoMapperExtensions.MapIEnumerableToList(s.TestProp)));
        Mapper.CreateMap<TestClassDto, TestClassLogical>().ReverseMap();
        //ToLogical
        Mapper.CreateMap<TestClassPLogical, TestClassPDto>()
            .ForMember(d => d.TestProp, o => o.MapFrom(s => AutoMapperExtensions.MapListToIEnumerable(s.TestProp)));
        Mapper.CreateMap<TestClassLogical, TestClassDto>().Reverse();
    }
}

的例外是:

AutoMapper。AutoMapperConfigurationException:以下属性on testclassplogic不能映射:

TestProp

添加自定义映射表达式、忽略、添加自定义解析器或修改目标类型TestClassLogical。上下文:映射到属性TestProp从TestClassDto到TestClassLogical映射到property TestProp fromSystem.Collections.Generic.List 1[[TestClassDto, TestMapper, Version=1.0.0.0, Culture=neutral, PublicKeyToken=null]] to System.Collections.Generic.List 1[[TestClassLogical, TestMapper,版本=1.0.0.0,文化=中性,PublicKeyToken=null]]映射从类型TestClassPDto to类逻辑异常类型AutoMapper。抛出AutoMapperConfigurationException'。在AutoMapper.ConfigurationStore。DryRunTypeMap(ICollection 1 typeMapsChecked, ResolutionContext context) at AutoMapper.ConfigurationStore.DryRunTypeMap(ICollection 1 typeMapsChecked, resoltioncontext context)在AutoMapper.ConfigurationStore。dryruntypemaps (ICollection 1 typeMapsChecked, ResolutionContext context) at AutoMapper.ConfigurationStore.AssertConfigurationIsValid(IEnumerable 1 typeMaps)assertconfigurationisvalid () atAutoMapper.Mapper.AssertConfigurationIsValid ()

Automapper在将泛型IEnumerable映射到泛型List时失败

你让事情变得比必要的更困难了。只要映射你需要的所有类对,AutoMapper就可以将嵌套的源集合映射到嵌套的目标集合。

请看Linqpad中的这个小例子(我用了一些不那么容易混淆的名字):

void Main()
{
    Mapper.CreateMap<Parent,ParentDto>().ReverseMap();
    Mapper.CreateMap<Child,ChildDto>().ReverseMap();
    Mapper.AssertConfigurationIsValid();
    var par = new Parent { TestProp = new List<Child> 
                           { new Child(),
                             new Child() 
                           }
                         };
    Mapper.Map<ParentDto>(par).Dump();
    Mapper.Map<Parent>(Mapper.Map<ParentDto>(par)).Dump();
}
class Parent
{
    public List<Child> TestProp{ get; set; }
}
class Child {}
class ParentDto
{
    public IEnumerable<ChildDto> TestProp{ get; set; }
}
class ChildDto {}

Dump语句输出:

ParentDto
 - ChildDto 
 - ChildDto 
Parent
 - Child 
 - Child 

在了解了'ReverseMap()'究竟是做什么的情况下,我向下钻取了我的代码。

我已经将TestClass映射为:

public class TestClassMapper
{
    public static void Configure()
    {
        //ToDto
        Mapper.CreateMap<TestClassDto, TestClassPLogical>();
        //ToLogical
        Mapper.CreateMap<TestClassLogical, TestClassDto>();
    }
}

现在,每当我尝试'ReverseMap()'由@Gert Arnold建议,它调用映射两次,一个是与ReverseMap和另一个是与Configure()方法,这打破了一切。

注::我有许多子类,如

TestClassPLogical 
TestClassLogical 
TestClass1Logical 
TestClass2Logical
TestClass3Logical

这是我修改后的代码片段:

public class TestClassPMapper
{
    public static void Configure()
    {
        //ToDto
        Mapper.CreateMap<TestClassPDto, TestClassPLogical>();
        //ToLogical
        Mapper.CreateMap<TestClassPLogical, TestClassPDto>();
        //What I changed
        TestClassMapper.Configure();
    }
}

下面的代码是工作的,当我删除Configure()方法,并做如下调用:

Mapper.CreateMap<TestClassPDto, TestClassPLogical>().ReverseMap()
Mapper.CreateMap<TestClassDto, TestClassLogical>().ReverseMap()

注:

  • 现在有了以上的变化,即使是地图道具也不需要了泛型IEnumerable <=>列表。
  • 我需要使用.MapFrom()只对那些成员/道具,这需要某种定制,像我需要映射Full_Name,这应该是First_Name + ' ' + Last_Name

最后,我的单元测试通过了:)

public class TestClassMapperTest
{
    [TestFixtureSetUp]
    public void Setup()
    {
        TestClassMapper.Configure();
    }
    [Test]
    public void EnsureFieldsAreAllMappedOrIgnored()
    {
        Mapper.AssertConfigurationIsValid();
    }
}