AutoMapper.Map忽略源对象的所有Null值属性

我正在尝试映射2个相同类型的对象。 我想要做的是AutoMapper to toigonore所有属性,在源对象中具有Null值,并保留目标对象中的现有值。

我已经尝试在我的“存储库”中使用它,但它似乎不起作用。

 Mapper.CreateMap().ForAllMembers(p => p.Condition(c => !c.IsSourceValueNull)); 

可能是什么问题?

有趣,但你最初的尝试应该是要走的路。 以下测试为绿色:

 using AutoMapper; using NUnit.Framework; namespace Tests.UI { [TestFixture] class AutomapperTests { public class Person { public string FirstName { get; set; } public string LastName { get; set; } public int? Foo { get; set; } } [Test] public void TestNullIgnore() { Mapper.CreateMap() .ForAllMembers(opt => opt.Condition(srs => !srs.IsSourceValueNull)); var sourcePerson = new Person { FirstName = "Bill", LastName = "Gates", Foo = null }; var destinationPerson = new Person { FirstName = "", LastName = "", Foo = 1 }; Mapper.Map(sourcePerson, destinationPerson); Assert.That(destinationPerson,Is.Not.Null); Assert.That(destinationPerson.Foo,Is.EqualTo(1)); } } } 

使用3个参数的Condition重载让你使表达式等同于你的示例p.Condition(c => !c.IsSourceValueNull)

方法签名:

 void Condition(Func condition 

等价表达式:

 CreateMap.ForAllMembers( opt => opt.Condition((src, dest, sourceMember) => sourceMember != null)); 

到目前为止,我已经解决了这个问题。

 foreach (var propertyName in entity.GetType().GetProperties().Where(p=>!p.PropertyType.IsGenericType).Select(p=>p.Name)) { var value = entity.GetType().GetProperty(propertyName).GetValue(entity, null); if (value != null) oldEntry.GetType().GetProperty(propertyName).SetValue(oldEntry, value, null); } 

但仍希望使用AutoMapper找到解决方案

将Marty的解决方案(可行)更进一步,这是一个使其更易于使用的通用方法:

 public static U MapValidValues(T source, U destination) { // Go through all fields of source, if a value is not null, overwrite value on destination field. foreach (var propertyName in source.GetType().GetProperties().Where(p => !p.PropertyType.IsGenericType).Select(p => p.Name)) { var value = source.GetType().GetProperty(propertyName).GetValue(source, null); if (value != null && (value.GetType() != typeof(DateTime) || (value.GetType() == typeof(DateTime) && (DateTime)value != DateTime.MinValue))) { destination.GetType().GetProperty(propertyName).SetValue(destination, value, null); } } return destination; } 

用法:

 class Person { public string Name { get; set; } public int? Age { get; set; } public string Role { get; set; } } Person person = new Person() { Name = "John", Age = 21, Role = "Employee" }; Person updatePerson = new Person() { Role = "Manager" }; person = MapValidValues(updatePerson, person); 

解决方法 – 如果源值为null,则在目标类型[DataMember(EmitDefaultValue = false)]中添加DataMember属性将删除该属性。

 [DataContract] class Person { [DataMember] public string Name { get; set; } [DataMember] public int? Age { get; set; } [DataMember(EmitDefaultValue = false)] public string Role { get; set; } } 

如果Role值为null将删除Role属性。