2017-08-02 41 views
0

我不能用AutoMapper來解決我的問題,也沒有找到正確的關鍵字來在線查找解決方案,因此這個問題可能是錯誤的標題,這裏是我的問題:使用AutoMapper來使用派生對象的地圖而不是父對象

我想強制AutoMapper使用兩張有效地圖中的一張地圖。這裏的爲例:

public class A 
{ 
    public B B { get; set; } 
} 

public class ADTO 
{ 
    public BDTO B { get; set; } 
} 

public class B 
{ 
} 

public class BDTO 
{ 
} 

public class CDTO : BDTO 
{ 
} 

public class AProfile : Profile 
{ 
    public AProfile() 
    { 
     Mapper.CreateMap<B, BDTO>(); 
     Mapper.CreateMap<B, CDTO>(); 

     // Is there a way to force AutoMapper to use B to CDTO instead of B to BDTO ? 
     Mapper.CreateMap<A, ADTO>() 
      .ForMember(adto => adto.B, opt => opt.MapFrom(a => a.B)); 
    } 
} 

如果我刪除以下行,AutoMapper拋出一個錯誤,指出它無法找到B房產的有效MAP,在以ADTO地圖。

Mapper.CreateMap<B, BDTO>(); 

有什麼辦法讓我的地圖B到CDTO有效嗎?從盧西恩

編輯回答

所以我想一個解決方案是讓兩個步驟:

var a = new A { B = new B() } 
var adto = new ADTO(); 

adto = Mapper.Map(a, adto); // Map B to BDTO 
adto.B = Mapper.Map<CDTO>(a.B); // Change BDTO to CDTO 

我更到一個合適的線路解決方案:

var a = new A { B = new B() } 
var adto = new ADTO(); 

adto = Mapper.Map(a, adto); // Map directly B to CDTO 

任何方式來實現它?

EDIT 2從盧西恩回答再次

事實是,A和B是從EF未來實體和我使用.ProjectTo擴展我沒有訪問ADTO初始化。

我的代碼是更多的東西一樣:

var adto = db.As.ProjectTo<ADTO>().ToList(); 

哪裏db是我DbContextAs我的ADbSet。從盧西恩答案

編輯3再次

我不知道這ConstructProjectionUsing方法,感謝您的!這裏我設法用你的答案來構建代碼。

Mapper.CreateMap<A, ADTO>() 
    .ConstructProjectionUsing(a => new ADTO() { B = new CDTO() }) 
    .ForMember(adto => adto.B, opt => opt.MapFrom(a => a.B)); 

而且很明顯!但現在,我還有另一個問題,B和BDTO實際上是ICollection和IEnumerable ...我不認爲這會是一個問題,所以我沒有告訴。在這裏,更新的代碼:

public class A 
{ 
    public ICollection<B> B { get; set; } 
} 

public class ADTO 
{ 
    public IEnumerable<BDTO> B { get; set; } 
} 

所以我覺得我不能使用ConstructProjectionUsing,因爲這代碼不能編譯:

Mapper.CreateMap<A, ADTO>() 
    .ConstructProjectionUsing(a => new ADTO() { B = new List<CDTO>() }) // Error here, can't convert List<CDTO> to List<BDTO> 
    .ForMember(adto => adto.B, opt => opt.MapFrom(a => a.B)); 

我想我被困在這裏?

回答

1

好的,所以你可以重定向地圖。它似乎與ProjectTo一起工作。見here

Mapper.CreateMap<B, BDTO>().As<CDTO>(); 

當然這適用於任何地方,不僅適用於ProjectTo。

+0

就是這樣,像魅力一樣工作。真的很感謝你盧西恩。 – dbraillon

1

您可以使用CDTO實例初始化ADTO.B並映射到現有對象。

var a = new A { B = new B() }; 
var adto = new ADTO { B = new CDTO() }; 
Mapper.Map(a, adto); // Map directly B to CDTO 

這將適用於較新的AM。您可能需要使用舊版本的UseDestinationValue。

+0

感謝您的回答,我更新了我的帖子並提供了您的建議。 – dbraillon

+0

嗯可能實際上適用於這種情況,但我沒有訪問ADTO初始化,因爲我使用.ProjectTo擴展方法。 A和B是來自EF的實體。 讓我再次更新我的文章。 – dbraillon

1

對於施工,您可以使用ConstructProjectionUsing。 An example。但除此之外,我認爲你需要在目的地的正確類型。

+0

好吧,您再次爲我暴露的問題提供了正確的答案,並且再次,這不適用於我的真實場景......讓我再次更新我的帖子。 – dbraillon

相關問題