2012-07-20 14 views
3

我有以下的採樣對象..AutoMapper地圖的屬性如果不爲null

public class ComplexObject 
    { 
    public string Name { get; set; } 
    public SimpleObject Child1 { get; set; } 
    public SimpleObject Child2 { get; set; } 
    } 
    public class SimpleObject : IEquatable<SimpleObject> 
    { 
    public string FirstName { get; set; } 
    public string LastName { get; set; } 
    public string Gender { get; set; } 
    public int? Age { get; set; } 
    } 

具有以下AutoMapper配置

Mapper.CreateMap<SimpleObject, SimpleObject>() 
    .ForAllMembers(expression=>expression.Condition(r=>!r.IsSourceValueNull)); 

    Mapper.CreateMap<ComplexObject, ComplexObject>() 
    .ForAllMembers(expression=>expression.Condition(resolutionContext=>!resolutionContext.IsSourceValueNull)); 

及以下NUnit測試...

[SetUp] public void Should_run_before_each_test() 
{ 
    child1 = new SimpleObject { FirstName = "Tom", LastName = "Smith", Age = 34, Gender = "Male" }; 
    child2 = new SimpleObject { FirstName = "Andy", LastName = "Smith-bob", Age = 21, Gender = "Male" }; 
} 

[ Test ] 
public void Should_ignore_null_properties_in_nested_objects() 
{ 
    var source = new ComplexObject() 
    { 
    Name = "blue", 
    Child1 = new SimpleObject{FirstName = "dot", LastName = "net"} 
    }; 
    var destination = new ComplexObject() 
    { 
    Name = "Andy", 
    Child1 = child1, 
    Child2 = child2 
    }; 

    destination = Mapper.Map(source, destination); 

    destination.Name.Should(Be.EqualTo(source.Name)); 
    destination.Child1.FirstName.Should(Be.EqualTo("dot")); 
    destination.Child1.LastName.Should(Be.EqualTo("net") ); 
    destination.Child1.Age.Should(Be.EqualTo(child1.Age) ); 
    destination.Child1.Gender.Should(Be.EqualTo(child1.Gender) ); 
} 

上述測試在斷言年齡爲AutoMapper將null推送到目的地時失敗對象。

我是否期待AutoMapper太多,或者我錯過了一些重要的地圖配置步驟。

最終目標是通過MVC操作將一個非常複雜的域對象綁定到傳入表單數據。然後,AutoMapper將被用來將非空屬性(在對象圖的所有深度處)合併到通過多步形式維護的實際實例中。

以防萬一有人需要知道......我也曾嘗試以下映射配置沒有任何運氣:(

Mapper.CreateMap<ComplexObject, ComplexObject>() 
    .ForMember(x=>x.Child1, l=>l.ResolveUsing(x=>x.Child1 == null?null:Mapper.Map<SimpleObject,SimpleObject>(x.Child1))) 
    .ForMember(x=>x.Child2, l=>l.ResolveUsing(x=>x.Child2 == null?null:Mapper.Map<SimpleObject,SimpleObject>(x.Child2))) 
    .ForAllMembers(expression=>expression.Condition(resolutionContext=>!resolutionContext.IsSourceValueNull)); 

回答

1

你爲什麼想到如果源的目標對象上的值不爲空值爲null嗎?int?的默認值是null,因此,當你調用

destination.Child1.Age.Should(Be.EqualTo(child1.Age));

.Should是什麼失敗。這應該被預期的行爲。

嘗試類似Assert.Null(detination.Child1.Age),它應該通過。 AutoMapper不是'推動'通過的值,沒有源值,因此,Age只是將它的默認值。

+0

都能跟得上..不是當我試圖說服AutoMapper忽略空源的值作爲每下面所嘗試的映射.. 'Mapper.CreateMap () .ForAllMembers(表達式=>表達。條件(r =>!r.IsSourceValueNull));' – andycwk 2012-07-20 14:14:01

+0

你可以添加你分配給'child1'和'child2'的東西嗎? – scottm 2012-07-20 14:16:22

+0

問題在於,在你的例子中,它沒有將'SimpleObject'映射到'SimpleObject',它將'ComplexObject'映射到'ComplexObject'。因爲'source.Child1'不爲空,它只是將它分配給'destination.Child1'。 – scottm 2012-07-20 14:42:32

相關問題