Logo Questions Linux Laravel Mysql Ubuntu Git Menu
 

Null source collection emptying destination collection

Tags:

c#

automapper

I'm merging objects that have a List member. I'm telling AutoMapper to ignore null source members but when I merge in an object with a null collection, the destination get's an empty collection (even though it had items before the map).

Any ideas on how to prevent this?

        ConfigurationInfo template1 = new ConfigurationInfo() {
            Columns = null //1st templates list of columns is null
        };

        ConfigurationInfo template2 = new ConfigurationInfo() {
            Columns = new List<ColumnInfo>()
        };
        template2.Columns.AddRange(existingColumns); //template2.Columns.Count == 9

        ConfigurationInfo template3 = new ConfigurationInfo() {
            Columns = null //3rd templates list of columns is null
        };

        var config = new AutoMapper.MapperConfiguration(cfg => {
            cfg.AllowNullCollections = true;
            cfg.AllowNullDestinationValues = true;

            cfg.CreateMap<ConfigurationInfo, ConfigurationInfo>()
                .ForAllMembers(option => {
                    //explicitly telling automapper to ignore null source members...
                    option.Condition((source, destination, sourceMember, destMember) => sourceMember != null);
                });

        });

        var mapper = config.CreateMapper();

        ConfigurationInfo finalTemplate = new ConfigurationInfo();

        mapper.Map(template1, finalTemplate); 
        //finalTemplate.Columns == null, which is exptected
        mapper.Map(template2, finalTemplate); 
        //finalTemplate.Columns.Count == 9, still exptected
        mapper.Map(template3, finalTemplate); 
        //finalTemplate.Columns.Count == 0, expecting 9 b/c 3rd template.Columns == null so AutoMapper should ignore. why is this happening?
like image 244
lestersconyers Avatar asked Mar 27 '17 21:03

lestersconyers


1 Answers

I have been struggling with the same thing. There are a couple configurations that are supposed to solve this very issue but they don't work in my case. Maybe they will work for you.

In this case its in global configuration.

 Mapper.Initialize(cfg =>
{
      cfg.AllowNullCollections = true;
      cfg.AllowNullDestinationValues = true;
}

Here is the feature request I created in their repo. They do suggest some work arounds that might help you.

https://github.com/AutoMapper/AutoMapper/issues/2341

Also, the check that you have for null source properties wont work for value types. You have to check for null or default. For that part I have created an extension:

public static bool IsNullOrDefault(this object obj)
{
    return obj == null || (obj.GetType() is var type && type.IsValueType  && obj.Equals(Activator.CreateInstance(type)));
}
like image 184
DonO Avatar answered Oct 18 '22 19:10

DonO