Automapper overwrites missing source property on l

2019-02-19 04:33发布

问题:

I have a problem with Automapper. I set up a test windows form application and below is the code. Also look at the comments after each MessageBox:

public class FirstClass
    {
        public string FirstProp { get; set; }
        public IList<FirstClassChild> Children { get; set; }
    }

    public class FirstClassChild
    {
        public string FirstChildProp { get; set; }
    }

    public class SecondClass
    {
        public string FirstProp { get; set; }
        public string SecondProp { get; set; }
        public IList<SecondClassChild> Children { get; set; }
    }

    public class SecondClassChild
    {
        public string FirstChildProp { get; set; }
        public string SecondChildProp { get; set; }
    }

    public partial class Form1 : Form
    {
        public Form1()
        {
            InitializeComponent();

            AutoMapper.Mapper.CreateMap<FirstClass, SecondClass>();
            AutoMapper.Mapper.CreateMap<FirstClassChild, SecondClassChild>();

            var f = new FirstClass { FirstProp = "FirstClass" };
            f.Children = new List<FirstClassChild> { new FirstClassChild { FirstChildProp = "FirstClass" } };
            var s = new SecondClass { FirstProp = "SecondClass", SecondProp = "SecondClass" };
            s.Children = new List<SecondClassChild> { new SecondClassChild { FirstChildProp = "SecondClass", SecondChildProp = "SecondClass" } };
            AutoMapper.Mapper.Map(f, s);

            var fc = new FirstClassChild { FirstChildProp = "FirstClass" };
            var sc = new SecondClassChild { FirstChildProp = "SecondClass", SecondChildProp = "SecondClass" };
            AutoMapper.Mapper.Map(fc, sc);

            MessageBox.Show(sc.FirstChildProp);//FirstClass as expected
            MessageBox.Show(sc.SecondChildProp);//SecondClass as expected

            MessageBox.Show(s.FirstProp);//FirstClass as expected
            MessageBox.Show(s.SecondProp);//SecondClass as expected
            MessageBox.Show(s.Children.First().FirstChildProp);//FirstClass as expected
            MessageBox.Show(s.Children.First().SecondChildProp);//Empty not expected!!

        }
    }

What can I do to avoid this? Is this behavior expected? Anyway can anyone guide me how make SecondClass childs SecondChildProp to remain "SecondClass" as it is before the mapping occurs.

回答1:

I asked a similar question here and found another similar one here.

I think @PatrickSteele makes a very good point: how is AutoMapper supposed to map a source list to a dest list of existing objects, when the dest list may not necessarily bear any resemblance to the source list? i.e. "But what if one list has 3 and the other list has 5?"

If you are sure that FirstClass and SecondClass have the same number of Children, and if the FirstClass's Nth Child always corresponds to SecondClass's Nth child, you could try something like this:

Mapper.CreateMap<FirstClass, SecondClass>()
    .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]);
        });

or if FirstChildProp is some kind of unique key:

Mapper.CreateMap<FirstClass, SecondClass>()
    .ForMember(m => m.Children, o => o.Ignore())
    .AfterMap((src, dest) =>
        {
            foreach (var dChild in dest.Children)
            {
                var sChild = src.Children.Single(c => c.FirstChildProp == dChild.FirstChildProp);
                Mapper.Map(sChild, dChild);
            }
        });


标签: c# AutoMapper