2017-03-27 12 views
4

Listメンバーを持つオブジェクトをマージしています。私はAutoMapperにnullソースメンバーを無視するように指示していますが、nullコレクションを持つオブジェクトをマージすると、(マップの前に項目があるにもかかわらず)宛先が空のコレクションを取得します。nullソースコレクションの空の宛先コレクション

これを防止する方法についてのご意見はありますか?

 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? 

答えて

1

私は同じことで苦労しています。この問題を解決するはずの構成がいくつかありますが、私の場合は動作しません。多分彼らはあなたのために働くでしょう。

この場合、グローバル設定です。

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

私は彼らのレポで作成した機能リクエストです。彼らはあなたに役立ついくつかの回避策を提案します。

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

また、あなたがnullのソースプロパティを持っているチェックは、値型のために仕事を文句を言いません。 nullまたはデフォルトを確認する必要があります。その部分については、私は拡張子を作成しました:これまで

public static bool IsNullOrDefault(this object obj) 
{ 
    return obj == null || (obj.GetType() is var type && type.IsValueType && obj.Equals(Activator.CreateInstance(type))); 
} 
-1

私の最善の解決策は、ExpandoObjectでマッピングする前に、宛先にはExpandoをマッピングするよりも、ヌルのプロパティをフィルタリングすることでした。

 var patchTemplate = new ExpandoObject() as IDictionary<string, object>; 

     foreach (var property in updatedTemplateDetails.GetType().GetProperties()) 
      if (property.GetValue(updatedTemplateDetails) is var propertyValue && propertyValue != null) 
       patchTemplate.Add(property.Name, propertyValue); 

     Mapper.Map(patchTemplate, finalTemplate); 
0

IEnumerableのマッピングをオーバーライドすることは可能です。

public class IgnoringNullValuesTypeConverter<T> : ITypeConverter<T, T> where T : class 
{ 
    public T Convert(T source, T destination, ResolutionContext context) 
    { 
     return source ?? destination; 
    } 
} 

cfg.CreateMap<IEnumerable, IEnumerable>().ConvertUsing(new IgnoringNullValuesTypeConverter<IEnumerable>()); 

この場合は動作しますが、普遍的な解決策ではありません。

関連する問題