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(ICollection1 typeMapsChecked, ResolutionContext context) at AutoMapper.ConfigurationStore.DryRunTypeMap(ICollection
1 typeMapsChecked, resoltioncontext context)在AutoMapper.ConfigurationStore。dryruntypemaps (ICollection1 typeMapsChecked, ResolutionContext context) at AutoMapper.ConfigurationStore.AssertConfigurationIsValid(IEnumerable
1 typeMaps)assertconfigurationisvalid () atAutoMapper.Mapper.AssertConfigurationIsValid ()
你让事情变得比必要的更困难了。只要映射你需要的所有类对,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();
}
}