3

次のサンプル オブジェクトがあります。

  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 を宛先オブジェクトにプッシュしているため、age をアサートすると失敗します。

AutoMapper に期待しすぎているのでしょうか、それとも重要なマップ構成ステップを見逃しているのでしょうか。

最終的な目標は、MVC アクションを介して非常に複雑なドメイン オブジェクトを受信フォーム データにバインドすることです。次に、AutoMapper を使用して、(オブジェクト グラフのすべての深さで) null 以外のプロパティのみを、マルチ ステップ フォーム全体で維持されている実際のインスタンスにマージします。

誰かが知る必要がある場合に備えて...次のマッピング構成も試しましたが、運がありません:(

  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));
4

1 に答える 1

1

ソース値がnullの場合、宛先オブジェクトの値がnullではないと予想するのはなぜですか?のデフォルト値int?null、であるため、

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

.Should失敗しているのはです。これは予想される動作です。

のようなものを試してみてくださいAssert.Null(detination.Child1.Age)、そしてそれは合格するはずです。AutoMapperは値を「プッシュ」しません。ソース値がないため、Ageデフォルト値になります。

于 2012-07-20T14:11:44.693 に答える