2013-03-22 69 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

相关问题