Welcome to OGeek Q&A Community for programmer and developer-Open, Learning and Share
Welcome To Ask or Share your Answers For Others

Categories

0 votes
1.5k views
in Technique[技术] by (71.8m points)

c# - Using AutoMapper to merge objects

I'm attempting to use AutoMapper to merge data from multiple objects, and I'm running into a couple issues that I can't seem to solve.

I have an object like:

public class Parent
{
    public string Id { get; set; }
    public List<Child> Children { get; set; }
}
public class Child
{
    public string Key { get; set; }
    public int? Value1 { get; set; }
    public int? Value2 { get; set; }
    public int? Value3 { get; set; }
    public int? Value4 { get; set; }
    public int? Value5 { get; set; }
}

Obviously the child properties are not all ints, but most of them are nullable.

I have these objects in two different tiers of my application, so I'm using AutoMapper to convert between them:

{
    Mapper.CreateMap<Parent, ParentDTO>();
    Mapper.CreateMap<ParentDTO, Parent>();

    Mapper.CreateMap<Child, ChildDTO>();
    Mapper.CreateMap<ChildDTO, Child>();
}

The conversion works well, and I'm happy with what it does. However, now I have a need to merge multiple objects of the same type. I will have one copy of an object which has most or all of the properties populated, and another copy which only has a few, with the rest being null. I want any non-null properties of the second (partial) object to be mapped to the respective field in the first (already filled out) object. As the accepted answer to this answer states, I should be able to use AutoMapper to do this as well, but it doesn't give any clear examples.

However, when I go to perform the operation, I get an object that is identical to either of the objects, not combined like I want.

{
    var bigParent = new Parent
    {
        Id = "14",
        Children = new List<Child>
        {
            new Child
            {
                Key = "A",
                Value1 = 10,
                Value2 = 20,
                Value3 = 30,
                Value4 = 40,
                Value5 = 50
            }                   
        }
    };

    var merge = new Parent
    {
        Id = "14",
        Children = new List<Child>
        {
            new Child
            {
                Key = "A",
                Value1 = null,
                Value2 = null,
                Value3 = 100,
                Value4 = null,
                Value5 = null
            }
        }
    };

    var res = Mapper.Map(merge, bigParent);
}

I am expecting Child to have values of 10, 20, 100, 40 and 50. However, depending on if I put merge as source or destination in Mapper.Map I get either null, null, 100, null, null or 10, 20, 30, 40, 50.

Is there a way I can get my expected values? I'm thinking having the List is what is causing the issues, since it won't know how to line up the entities (to determine if they are the same or not). If is answers any questions, I would be able to identify if child records are the same by seeing if one or more properties are the same (in this example, Key).

See Question&Answers more detail:os

与恶龙缠斗过久,自身亦成为恶龙;凝视深渊过久,深渊将回以凝视…
Welcome To Ask or Share your Answers For Others

1 Reply

0 votes
by (71.8m points)

If you want to ignore null values in mappings defined in AutoMapper Profile, use:

public class MappingProfile : AutoMapper.Profile
{
  public MappingProfile()
  {
     this.CreateMap<Parent, Parent>()
         .ForAllMembers(o => o.Condition((source, destination, member) => member != null));
  }
}

与恶龙缠斗过久,自身亦成为恶龙;凝视深渊过久,深渊将回以凝视…
OGeek|极客中国-欢迎来到极客的世界,一个免费开放的程序员编程交流平台!开放,进步,分享!让技术改变生活,让极客改变未来! Welcome to OGeek Q&A Community for programmer and developer-Open, Learning and Share
Click Here to Ask a Question

...