在Asp.net (core)中使用AutoMapper(2)inDepth

上一篇文章中,我們知道了如何在asp.net中使用Automapper,這次,我們進(jìn)行深入了解

CreateMap方法

CreateMap是一個(gè)單向mapping,也就是說(shuō),如果定義了這樣的mapper:

AutoMapper.Mapper.CreateMap<Book, BookViewModel>();

我們就可以將Book映射到BookViewModel: var bookViewModel = AutoMapper.Mapper.Map<BookViewModel>(book);; 但是,如果反向映射,則會(huì)報(bào)錯(cuò):var book = AutoMapper.Mapper.Map<Book>(bookViewModel);.
我們當(dāng)然可以定義多個(gè)映射:

AutoMapper.Mapper.CreateMap<Book, BookViewModel>();
AutoMapper.Mapper.CreateMap<BookViewModel, Book>();

但如果兩個(gè)類沒(méi)有什么特殊轉(zhuǎn)換,我們也可以簡(jiǎn)單的使用reverse映射:

AutoMapper.Mapper.CreateMap<Book, BookViewModel>().ReverseMap();

這樣兩個(gè)類就可以來(lái)回互轉(zhuǎn)了。

Conventions-約定

Automapper的最基本約定是,轉(zhuǎn)換源和目標(biāo)的字段名相同時(shí)將會(huì)自動(dòng)對(duì)應(yīng):

public class Book
{
    public string Title { get; set; }
}

public class NiceBookViewModel
{
    public string Title { get; set; }
}

public class BadBookViewModel
{
    public string BookTitle { get; set; }
}

按照約定,NiceBookViewModel和Book類具有相同字段,可以自動(dòng)mapping,但是BadBookViewModel字段名不一致所以無(wú)法對(duì)應(yīng)。我們就必須自定義映射關(guān)系:

AutoMapper.Mapper.CreateMap<Book, BadBookViewModel>()
    .ForMember(dest => dest.BookTitle,
               opts => opts.MapFrom(src => src.Title));

另一個(gè)約定是包含類名稱約定,如:

public class Author
{
    public string Name { get; set; }
}

public class Book
{
    public string Title { get; set; }
    public Author Author { get; set; }
}

public class BookViewModel
{
    public string Title { get; set; }
    public string Author { get; set; }
}

盡管Book類和BookViewModel類都含有Author,(一個(gè)是類名,一個(gè)是字段名),automaper都無(wú)法自動(dòng)映射。但如果我們對(duì)BookViewModel稍作修改:

public class BookViewModel
{
    public string Title { get; set; }
    public string AuthorName { get; set; }
}

即可以了。其實(shí)AuthorName字段就相當(dāng)于Author.Name。
這種約定雖然方便,但還是建議大家手動(dòng)指定mapper放心一點(diǎn):

AutoMapper.Mapper.CreateMap<Book, BookViewModel>()
    .ForMember(dest => dest.Author,
               opts => opts.MapFrom(src => src.Author.Name));

復(fù)雜映射

如果Author類是這個(gè)樣子:

public class Author
{
    public string FirstName { get; set; }
    public string LastName { get; set; }
}

而我們想將其映射到BookViewModel中,而且用BookViewModel中的一個(gè)字段包含全名,該怎么做呢?

AutoMapper.Mapper.CreateMap<Book, BookViewModel>()
    .ForMember(dest => dest.Author,
               opts => opts.MapFrom(
                   src => string.Format("{0} {1}",
                       src.Author.FirstName,
                       src.Author.LastName)));

對(duì)目標(biāo)類中的Author字段,我們使用源類中的FirstName+LastName進(jìn)行替換。

更加復(fù)雜的映射

上面的例子是將源類在目標(biāo)類中進(jìn)行組合,如果我們想使用源類“組合”成目標(biāo)類怎么辦呢?

public class Address
{
    public string Street { get; set; }
    public string City { get; set; }
    public string State { get; set; }
    public string ZipCode { get; set; }
}

public class Person
{
    public string FirstName { get; set; }
    public string LastName { get; set; }
    public Address Address { get; set; }
}

public class PersonDTO
{
    public string FirstName { get; set; }
    public string LastName { get; set; }
    public string Street { get; set; }
    public string City { get; set; }
    public string State { get; set; }
    public string ZipCode { get; set; }
}

我們想建立PersonDTO→Person類映射,那可以這樣:

AutoMapper.Mapper.CreateMap<PersonDTO, Person>()
    .ForMember(dest => dest.Address,
               opts => opts.MapFrom(
                   src => new Address
                   {
                       Street = src.Street,
                       City = src.City,
                       State = src.State,
                       ZipCode = src.ZipCode
                   }));

BTW,這種情況非常多見(jiàn),前臺(tái)傳進(jìn)來(lái)的表單字段(PersonDTO),可以通過(guò)mapping自動(dòng)組成復(fù)雜類(Person),爽歪歪。

mapping到新實(shí)例 vs mapping到已有實(shí)例

類似這樣:var destinationObject = AutoMapper.Mapper.Map<DestinatationClass>(sourceObject);的語(yǔ)法,舉例:var model = Mapper.Map<BookViewModel>(book);我們將創(chuàng)建一個(gè)目標(biāo)類的新實(shí)例。
但有時(shí)我們不想創(chuàng)建新實(shí)例,比如在Update時(shí),那我們可以用這樣的語(yǔ)法:AutoMapper.Mapper.Map(sourceObject, destinationObject);; 舉例:Mapper.Map<BookViewModel>(book,bookViewModel)

數(shù)組/列表的mapping

一般情況下,當(dāng)定義好了mapper,列表就可以被自動(dòng)mapping,不需要額外代碼

var destinationList = AutoMapper.Mapper.Map<List<DestinationClass>>(sourceList);

適用于所有集合類型: List<T>, ICollection<T>, IEnumerable<T>, etc.

?著作權(quán)歸作者所有,轉(zhuǎn)載或內(nèi)容合作請(qǐng)聯(lián)系作者
【社區(qū)內(nèi)容提示】社區(qū)部分內(nèi)容疑似由AI輔助生成,瀏覽時(shí)請(qǐng)結(jié)合常識(shí)與多方信息審慎甄別。
平臺(tái)聲明:文章內(nèi)容(如有圖片或視頻亦包括在內(nèi))由作者上傳并發(fā)布,文章內(nèi)容僅代表作者本人觀點(diǎn),簡(jiǎn)書(shū)系信息發(fā)布平臺(tái),僅提供信息存儲(chǔ)服務(wù)。

相關(guān)閱讀更多精彩內(nèi)容

友情鏈接更多精彩內(nèi)容