2

AutoMapper の使用: ネストされたコレクションをマッピングする場合、マッピングされていないプロパティには元の値が保持されていると思います。代わりに、null に設定されています。

例:
次の 4 つのクラスがあります (プロパティはありますが、ないことに
注意しTest2Childてください)。NameTest1Child

public class Test1
{
    public List<Test1Child> Children { get; set; }
}
public class Test2
{
    public List<Test2Child> Children { get; set; }
}
public class Test1Child
{
    public int Value { get; set; }
}
public class Test2Child
{
    public string Name { get; set; }
    public int Value { get; set; }
}

...そして簡単なマッピング設定。

Mapper.CreateMap<Test1, Test2>();
Mapper.CreateMap<Test1Child, Test2Child>().ForMember(m => m.Name, o => o.Ignore());
Mapper.AssertConfigurationIsValid();    // Ok

マッピング中に の元の値をTest2Child.Name保持したい....これが、マッピングされていないプロパティのデフォルトの動作になると思います。

Test1Childからに直接マップするとTest2Child、正常に動作します。Valueマップされ、Name保持されます。

var a = new Test1Child {Value = 123};
var b = new Test2Child {Name = "fred", Value = 456};
Mapper.Map(a, b);
Assert.AreEqual(b.Value, 123);    // Ok
Assert.AreEqual(b.Name, "fred");  // Ok

ネストされたコレクション ( List<Test1Child>to List<Test2Child>)に対するマッピングの場合、
Valueは正しくマッピングされますが、 の元の値Nameは失われます!

var c = new Test1 { Children = new List<Test1Child> { new Test1Child { Value = 123 } } };
var d = new Test2 { Children = new List<Test2Child> { new Test2Child { Name = "fred", Value = 456 } } };
Mapper.Map(c, d);
Assert.AreEqual(d.Children[0].Value, 123);    // Ok
Assert.AreEqual(d.Children[0].Name, "fred");  // FAILS! Name is null.

これを修正するにはどうすればよいですか?

4

3 に答える 3

2

@MightyMukeの回答のコメントで述べたように、@PatrickSteeleはここで良い点を指摘います.ソースリストから宛先リストに各アイテムを自動的にマップするのは意味がないかもしれません....もう一方のリストには 5 つありますか?

私の場合、ソース リストと宛先リストは常に同じ長さであり、(重要なことに) ソース リストの N 番目の項目は常に宛先リストの N 番目の項目に直接対応することを知っています。

だから、これはうまくいきますが、私は自分自身について気分が良くありません....

Mapper.CreateMap<Test1, Test2>()
    .ForMember(m => m.Children, o => o.Ignore())
    .AfterMap((src, dest) =>
        {
            for (var i = 0; i < dest.Children.Count; i++)
                Mapper.Map(src.Children[i], dest.Children[i]);
        });
于 2013-01-09T08:42:04.003 に答える
0

私は同じ問題に遭遇しました。基本的に、automapper は、元のオブジェクトと一致させるために、リスト オブジェクト内のキーが何であるかを認識していないため、オブジェクトを新しく作成します。プロパティを維持したい場合は、変更をマッピングできるように、元のアイテムに戻す方法を理解できるようにする必要があります。これを行うには、現在持っていないキーが必要です。

次のようなことを試してください。

public class Test1
{
    public List<Test1Child> Children { get; set; }
}
public class Test2
{
    public List<Test2Child> Children { get; set; }
}
public class Test1Child
{
    public int ChildId { get; set; }
    public int Value { get; set; }
}
public class Test2Child
{
    public int ChildId { get; set; }
    public string Name { get; set; }
    public int Value { get; set; }

    public Test2Child() 
    { }

    public Test2Child(int childId)
    {
        // of course you will need to load this from your data source, but for testing.  :)
        if (childId == 1)
        {
            ChildId = 1;
            Name = "fred";
            Value = 456;
        }
    }
}

Mapper.CreateMap<Test1, Test2>();
Mapper.CreateMap<Test1Child, Test2Child>()
    .ConstructUsing(t => t.ChildId > 0 ? new Child(t.ChildId) : new Child())
    .ForMember(m => m.Name, o => o.Ignore());

Mapper.AssertConfigurationIsValid();

var c = new Test1 { Children = new List<Test1Child> { new Test1Child { ChildId = 1, Value = 123 } } };
var d = new Test2 { Children = new List<Test2Child> { new Test2Child { ChildId = 1, Name = "fred", Value = 456 } } };
Mapper.Map(c, d);
Assert.AreEqual(d.Children[0].Value, 123);
Assert.AreEqual(d.Children[0].Name, "fred");
于 2013-01-14T21:09:30.237 に答える
0

UseDestinationValueこの同様の質問への回答で説明されているように 使用してみてください: Automapper overwrites missing source property on list with child objects

于 2013-01-09T07:57:42.967 に答える