我正在合并具有List成员的对象。我告诉AutoMapper忽略空源成员但是当我合并一个带有null集合的对象时,目标get是一个空集合(即使它在地图之前有项目)。
关于如何防止这种情况的任何想法?
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?
答案 0 :(得分:1)
我一直在努力做同样的事情。有一些配置可以解决这个问题,但它们不适用于我的情况。也许他们会为你工作。
在这种情况下,它处于全局配置中。
Mapper.Initialize(cfg =>
{
cfg.AllowNullCollections = true;
cfg.AllowNullDestinationValues = true;
}
这是我在他们的回购中创建的功能请求。他们确实建议了一些可能对你有用的工作。
https://github.com/AutoMapper/AutoMapper/issues/2341
此外,对null源属性的检查不适用于值类型。您必须检查null或default。对于那部分,我创建了一个扩展名:
public static bool IsNullOrDefault(this object obj)
{
return obj == null || (obj.GetType() is var type && type.IsValueType && obj.Equals(Activator.CreateInstance(type)));
}
答案 1 :(得分: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>());
在这种情况下它会起作用,但它不是通用解决方案。
答案 2 :(得分:0)
除了在the mapper configuration initialization中设置AllowNullCollections
,您还可以选择在映射器AllowNullCollections
中设置Profile
,如下所示:
public class MyMapper : Profile
{
public MyMapper()
{
// Null collections will be mapped to null collections.
AllowNullCollections = true;
CreateMap<MySource, MyDestination>();
}
}
答案 3 :(得分:-1)
我最好的解决方案是在ExpandoObject中映射之前过滤掉null属性,然后将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);