我正在尝试使用AutoMapper来合并来自多个对象的数据,而且我遇到了一些我似乎无法解决的问题。
我有一个像这样的对象:
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; }
}
显然,子属性并非都是整数,但大多数都可以为空。
我的应用程序有两个不同的层,因此我使用AutoMapper在它们之间进行转换:
{
Mapper.CreateMap<Parent, ParentDTO>();
Mapper.CreateMap<ParentDTO, Parent>();
Mapper.CreateMap<Child, ChildDTO>();
Mapper.CreateMap<ChildDTO, Child>();
}
转换效果很好,我对它的功能感到满意。但是,现在我需要合并多个相同类型的对象。我将有一个对象的一个副本,其中包含大部分或全部属性,另一个副本只有少数,其余为空。我希望第二个(部分)对象的任何非null属性都映射到第一个(已填充)对象中的相应字段。作为this answer州的公认答案,我应该能够使用AutoMapper来做到这一点,但它没有提供任何明确的例子。
然而,当我去执行操作时,我得到一个与任何一个对象相同的对象,而不是像我想要的那样组合。
{
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);
}
我希望Child的值为10,20,100,40和50.但是,根据我是否将合并作为源或目标放在Mapper.Map中,我得到null,null,100,null,null或10,20,30,40,50。
有没有办法可以达到预期的价值?我在想列表是导致问题的原因,因为它不知道如何排列实体(以确定它们是否相同)。如果回答任何问题,我将能够通过查看一个或多个属性是否相同来识别子记录是否相同(在此示例中为Key)。
答案 0 :(得分:4)
Automapper能够做到这一点,你的映射器需要这样配置:
Mapper.Initialize(cfg =>
{
// necessary if you are mapping parent to a parent
cfg.CreateMap<Parent, Parent>()
.ForAllMembers(options =>
{
options.Condition(src => src.DestinationValue == null);
});
// necessary if you are mapping your child to a child
cfg.CreateMap<Child, Child>()
.ForAllMembers(options =>
{
options.Condition(src => src.DestinationValue == null);
});
});
然后你的用法如下:
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 bigChild = new Child
{
Key = "A",
Value1 = 10,
Value2 = 20,
Value3 = 30,
Value4 = 40,
Value5 = 50
};
var mergeChild = new Child
{
Key = "A",
Value1 = null,
Value2 = null,
Value3 = 100,
Value4 = null,
Value5 = null
};
Mapper.Map(bigChild, mergeChild);
Debug.Assert(mergeChild.Value3 == 100);
Mapper.Map(bigParent, merge);
Debug.Assert(merge.Children[0].Value3 == 100);
答案 1 :(得分:4)
如果要忽略AutoMapper Profile中定义的映射中的空值,请使用:
public class MappingProfile : AutoMapper.Profile
{
public MappingProfile()
{
this.CreateMap<Parent, Parent>()
.ForAllMembers(o => o.Condition((source, destination, member) => member != null));
}
}