AutoMapper(六)


返回總目錄


List和數組

AutoMapper只要求元素類型的配置而不要求可能會用到的任何數組或者list類型。比如,我們有一個簡單的源和目標類型:

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

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

支持所有的基本泛型集合,代碼如下:

class Program
{
    static void Main(string[] args)
    {
        Mapper.CreateMap<Source, Destination>();
        var sources = new[]
        {
            new Source() {Value = 1},
            new Source() {Value = 2},
            new Source() {Value = 3},
        };
        IEnumerable<Destination> iEnumerableDests= Mapper.Map<IEnumerable<Destination>>(sources);
        ICollection<Destination> iCollectionDests= Mapper.Map<ICollection<Destination>>(sources);
        IList<Destination> iListDests= Mapper.Map<IList<Destination>>(sources);
        List<Destination> listDests= Mapper.Map<List<Destination>>(sources);
        Destination[] destsArr= Mapper.Map<Destination[]>(sources);
        //這里只舉兩個例子,其他集合同理
        foreach (var dest in iCollectionDests)
        {
            Console.Write(dest.Value+",");
        }
        Console.WriteLine();
        foreach (var dest in destsArr)
        {
            Console.Write(dest.Value + ",");
        }
    Console.Read();
}

}

以上代碼是集合和集合之間的映射,但是映射的配置CreateMap方法中只是配置的是類型之間的映射,而沒有設計任何集合類型。

測試結果如下,可見集合之間映射成功:

image

具體來說,支持的源集合類型包括:

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

集合中的多態元素類型

很多時候,在我們的源和目標類型中可能有一個類型層次關系。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仍然要求顯示配置孩子映射,因為它不能“猜出”具體使用哪一個孩子目標映射。

在Main方法中添加如下代碼:

Mapper.Initialize(c =>
{
    c.CreateMap<ParentSource, ParentDestination>()
        .Include<ChildSource, ChildDestination>();
    c.CreateMap<ChildSource, ChildDestination>();
});
var sources = new[]
{
    new ParentSource(){Value1 = 11},
    new ChildSource(){Value2 = 22},
    new ParentSource(),
};

var dests = Mapper.Map<ParentDestination[]>(sources);
Console.WriteLine(dests[
0]);
Console.WriteLine(dests[
1]);
Console.WriteLine(dests[
2]);

測試結果如下:

image

上面我們創建了一個源的數組,其中包含兩個ParentSource和一個ChildSource,所以兩個ParentSource成功地映射到了ParentDestination,而CreateMap配置中,ParentSource到ParentDestination的映射配置包含了ChildSource到ChildDestination的配置,所以執行Mapper.Map<ParentDestination[]>(sources)的時候,也可以將ChildSource映射到ChildDestination。

映射繼承

在派生類中標明繼承

上面的代碼,是在基類中配置繼承的,除此之外,也可以在派生類中配置繼承:

//在基類中配置繼承
 Mapper.Initialize(c =>
 {
     c.CreateMap<ParentSource, ParentDestination>()
         .Include<ChildSource, ChildDestination>();
     c.CreateMap<ChildSource, ChildDestination>();
 });
 //在派生類中配置繼承
 Mapper.Initialize(c =>
 {
     c.CreateMap<ParentSource, ParentDestination>();
     c.CreateMap<ChildSource, ChildDestination>()
         .IncludeBase<ParentSource, ParentDestination>();
 });

繼承映射屬性

這里介紹一下額外的復雜性,因為一個屬性映射時可以有多種方式。下面是這些源的優先級:

  • 顯式映射 (使用.MapFrom())
  • 繼承的顯式映射 
  • 慣例映射 (通過慣例匹配的屬性)
  • 忽略的屬性映射

下面來演示一下:

這里還是用上面定義的四個類:Order,OrderDto,PCOrder,MobileOrder:

//領域對象
public class Order { }
//電腦端訂單
public class PCOrder : Order
{
    public string Referrer { get; set; }
}
//手機訂單
public class MobileOrder : Order { }

//Dtos
public class OrderDto
{
public string Referrer { get; set; }
}

配置映射的方法使用的是在父類中配置繼承映射

//在父類中配置繼承映射
Mapper.CreateMap<Order, OrderDto>()
    .Include<PCOrder,OrderDto>()
    .Include<MobileOrder,OrderDto>()
    .ForMember(o => o.Referrer, m => m.Ignore());//這里配置了忽略目標屬性Referrer的映射
Mapper.CreateMap<PCOrder,OrderDto>();
Mapper.CreateMap<MobileOrder, OrderDto>();
// 執行映射
var order = new PCOrder() { Referrer = "天貓" };
var mapped = Mapper.Map<OrderDto>(order);
Console.WriteLine(mapped.Referrer);

執行結果如下:

image

注意在我們的映射配置中,我們已經忽略了Referrer(因為Order基類中不存在這個屬性),但是在基類的映射中,慣例比忽略的屬性有更高的優先級,因而屬性仍然得到了映射。


免責聲明!

本站轉載的文章為個人學習借鑒使用,本站對版權不負任何法律責任。如果侵犯了您的隱私權益,請聯系本站郵箱yoyou2525@163.com刪除。



 
粵ICP備18138465號   © 2018-2025 CODEPRJ.COM