2013-03-22 66 views
1

我最近從AutoMapper 2.2.0升級到2.2.1,並且我停止了正確的映射。下面是該方法的僞版本:AutoMapper 2.2.1 DynamicMap未映射底層類型屬性(2.2.0)

public void LoadModel<TModel>(int id, TModel model) where TModel : ModelBase 
{ 
    var entity = _repo.LoadById(id); 
    _mapper.DynamicMap(entity, model); 
    model.AfterMap(); // AfterMap is a virtual method in ModelBase 
} 

ModelBase由被傳遞到該方法的父類的實例繼承抽象類。在版本2.2.0中,來自entity實例的相應屬性已正確映射到model實例的ModelBase屬性;升級到版本2.2.1後,ModelBase上的屬性不再映射 - 沒有拋出異常,但屬性根本沒有設置。

更新: 下面是一個具體的例子,說明2.2.0和2.2.1之間的區別。在2.2.0版本中,輸出將是:

Male 
True 

在2.2.1版本的輸出將是:

Male 
False 

HumanIsEmployed屬性不被映射在2.2.1版本,但在版本2.2.0中。下面是示例代碼:

namespace TestAutomapper 
{ 
    using System; 

    class Program 
    { 
     static void Main(string[] args) 
     { 
      Tester tester = new Tester(); 
      tester.Test(); 
     } 
    } 

    public class Tester 
    { 
     public void Test() 
     { 
      var animal = (Animal)new Human(); 
      LoadModel(animal); 
      var human = (Human)animal; 
      Console.WriteLine(human.Gender); 
      Console.WriteLine(human.IsEmployed.ToString()); 
      Console.ReadLine(); 
     } 

     private void LoadModel<TModel>(TModel model) where TModel : Animal 
     { 
      var tim = new Developer { Gender = "Male", IsEmployed = true, KnownLanguages = 42 }; 
      AutoMapper.Mapper.DynamicMap(tim, model); 
     } 
    } 

    public abstract class Animal 
    { 
     public string Gender { get; set; } 
    } 

    public class Human : Animal 
    { 
     public bool IsEmployed { get; set; } 
    } 

    public class Developer 
    { 
     public string Gender { get; set; } 
     public bool IsEmployed { get; set; } 
     public int KnownLanguages { get; set; } 
    } 
} 

這個問題似乎涉及到的Human拳擊作爲Animal之前得到映射。我並不是說這是一個錯誤,但它在版本之間的表現會有所不同。

更新2:在我的例子中的抽象類是一個紅色的鯡魚;如果我使用名爲IAnimal的接口而不是名爲Animal的抽象類,則該示例適用。這個問題似乎清楚地表明,動態映射時,版本2.2.0考慮基礎類型,而版本2.2.1則不考慮。

+0

您能否展示一個突出顯示問題的完整代碼示例? – PatrickSteele 2013-03-26 18:28:01

+0

當然。讓我解決這個問題,然後編輯我的問題。 – 2013-03-27 12:48:47

回答

1

2.2.0和2.2.1之間的動態映射有關。

在2.2.0的代碼看起來是這樣的:

public void DynamicMap<TSource, TDestination>(TSource source, TDestination destination) 
{ 
    Type modelType = typeof(TSource); 
    Type destinationType = (Equals(destination, default(TDestination)) ? typeof(TDestination) : destination.GetType()); 

    DynamicMap(source, destination, modelType, destinationType); 
} 

和2.2.1:

public void DynamicMap<TSource, TDestination>(TSource source, TDestination destination) 
{ 
    Type modelType = typeof(TSource); 
    Type destinationType = typeof(TDestination); 

    DynamicMap(source, destination, modelType, destinationType); 
} 

所以有效地意味着在2.2.0動態映射目標類型是由目的地確定值。如果它爲空(對於參考類型),則從TDestination獲取目標;否則目標對象實例的類型決定了這一點。

在AutoMapper 2.2.1中,TDestination的類型優先,在你的情況下,它是Animal。

+0

所以在我的例子中,'typeof(TDestination)'返回類型'Animal',但'destination.GetType()'返回類型'Human'。說得通。我認爲這是爲了避免空引用異常,但它肯定會破壞我的代碼。我想我必須將2.2.0留在原地,除非我可以使用'typeof'而不是'.GetType()'來更新我的代碼。啊。謝謝(你的)信息。 – 2013-04-01 13:08:51

+0

已根據此信息找到需要的正確更新。引用我的示例代碼,我簡單地將這個'AutoMapper.Mapper.DynamicMap(tim,model);'改成了這個'AutoMapper.Mapper.DynamicMap(tim,model,tim.GetType(),model.GetType());'。感謝aguyngueran的洞察力。 – 2013-04-01 13:20:38