本文介绍了AutoMapper:将子集合1映射到子集合2时丢失未映射的属性值的处理方法,对大家解决问题具有一定的参考价值,需要的朋友们下面随着小编来一起学习吧!

问题描述

使用AutoMapper:映射嵌套集合时,我希望所有未映射的属性都保留其原始值.而是将它们设置为null.

Using AutoMapper: When mapping nested collections, I expect any unmapped properties to have their original values retained. Instead, they are being set to null.

示例:
我有这四个班
(请注意,Test2Child具有Name属性,而Test1Child没有):

Example:
I have these four classes
(note that Test2Child has the Name property, while Test1Child does not):

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; }
}

...以及一个简单的映射设置.

...and a simple mapping setup.

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

我希望在映射过程中保留Test2Child.Name的原始值....我希望这是所有未映射属性的默认行为.

I want the original value of Test2Child.Name to be retained during mapping.... I expect this to be the default behaviour for any unmapped properties.

当我直接从Test1Child映射到Test2Child时,它可以正常工作;映射Value并保留Name:

When I map directly from Test1Child to Test2Child, it works fine; Value is mapped and Name is retained:

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>List<Test2Child>)时,
Value已正确映射... Name的原始值丢失了!

When the mapping is for a nested collection (List<Test1Child> to List<Test2Child>),
Value is mapped correctly... but the original value for Name is lost!

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.

我该如何解决?

推荐答案

如@MightyMuke的答案的评论中所述,@ PatrickSteele很好地说明了这里:也许自动将每个项目从源列表映射到目标列表是没必要.即""

As mentioned in comments of @MightyMuke's answer, @PatrickSteele makes a good point here: maybe it doesn't make sense to automatically map each item from the source list to the destination list.... i.e. "But what if one list has 3 and the other list has 5?"

就我而言,我知道源列表和目标列表将始终具有相同的长度,并且(重要地)源列表中的第N个项始终始终与目标列表中的第N个项相对应.

In my case, I know that the source and dest lists will always have the same length, and (importantly) the Nth item in the source list is always the direct counterpart to the Nth item in the dest list.

所以,这行得通,但是我对自己并不满意....

So, this works, but I don't feel good about myself....

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]);
        });

这篇关于AutoMapper:将子集合1映射到子集合2时丢失未映射的属性值的文章就介绍到这了,希望我们推荐的答案对大家有所帮助,也希望大家多多支持!

09-03 07:47