项目
版本

AutoMapper 列表和数组

AutoMapper 只需配置元素类型,而不必关心可能使用的任何数组或列表类型。例如,我们可能有一个简单的源类型和目标类型:

public class Source
{
	public int Value { get; set; }
}

public class Destination
{
	public int Value { get; set; }
}

所有基本的泛型集合类型都受支持:

var configuration = new MapperConfiguration(cfg => cfg.CreateMap<Source, Destination>());

var sources = new[]
	{
		new Source { Value = 5 },
		new Source { Value = 6 },
		new Source { Value = 7 }
	};

IEnumerable<Destination> ienumerableDest = mapper.Map<Source[], IEnumerable<Destination>>(sources);
ICollection<Destination> icollectionDest = mapper.Map<Source[], ICollection<Destination>>(sources);
IList<Destination> ilistDest = mapper.Map<Source[], IList<Destination>>(sources);
List<Destination> listDest = mapper.Map<Source[], List<Destination>>(sources);
Destination[] arrayDest = mapper.Map<Source[], Destination[]>(sources);

具体来说,支持的源集合类型包括:

  • IEnumerable
  • IEnumerable<T>
  • ICollection
  • ICollection<T>
  • IList
  • IList<T>
  • List<T>
  • Arrays

对于非泛型的可枚举类型,只支持未映射且可分配的类型,因为 AutoMapper 无法 “猜测” 您尝试映射的类型。如上例所示,不必显式配置列表类型,只需配置它们的成员类型即可。

当映射到一个已存在的集合时,目标集合会先被清空。如果这不是你想要的,请查看 AutoMapper.Collection

处理空集合

在映射集合属性时,如果源值为 nullAutoMapper 会将目标字段映射为空集合,而不是将目标值设置为 null。这与 Entity Framework 和框架设计指南的行为一致,它们认为 C# 引用、数组、列表、集合、字典和 IEnumerables 永远不应为 null

可以通过在配置映射器时设置 AllowNullCollections 属性为 true 来改变这种行为。

var configuration = new MapperConfiguration(cfg => {
    cfg.AllowNullCollections = true;
    cfg.CreateMap<Source, Destination>();
});

该设置可以全局应用,并且可以使用 AllowNull DoNotAllowNull 在每个配置文件和成员级别上覆盖。

集合中元素类型的多态性

很多时候,我们的源类型和目标类型可能都有一个层次结构。AutoMapper 支持多态数组和集合,这样如果找到了派生的源/目标类型就会使用它们。

public class ParentSource
{
	public int Value1 { get; set; }
}

public class ChildSource : ParentSource
{
	public int Value2 { get; set; }
}

public class ParentDestination
{
	public int Value1 { get; set; }
}

public class ChildDestination : ParentDestination
{
	public int Value2 { get; set; }
}

AutoMapper 仍然需要为子映射提供明确的配置,因为 AutoMapper 不能 “猜测” 应使用哪个特定的子目标映射。以下是上述类型的示例:

var configuration = new MapperConfiguration(c=> {
    c.CreateMap<ParentSource, ParentDestination>()
	     .Include<ChildSource, ChildDestination>();
    c.CreateMap<ChildSource, ChildDestination>();
});

var sources = new[]
	{
		new ParentSource(),
		new ChildSource(),
		new ParentSource()
	};

var destinations = mapper.Map<ParentSource[], ParentDestination[]>(sources);

destinations[0].ShouldBeInstanceOf<ParentDestination>();
destinations[1].ShouldBeInstanceOf<ChildDestination>();
destinations[2].ShouldBeInstanceOf<ParentDestination>();
在本文档中