在开发过程中,难免遇到下面这种情况:两个(或多个)对象所拥有的大多数属性是重复的,我们需要在对象间进行映射(即将一个对象的属性值赋给另一个对象。通常我们可以进行如下操作:
1 A a=new A(); 2 a.Name=b.Name; 3 a.Age=b.Age;
但若对象拥有较多属性,采用着用方法将会显得十分繁琐。那么有没有一些框架可以帮助我们完成这个过程呢?答案是肯定的。
这里小编使用的是AutoMapper框架,这是一个轻量级的解决对象间映射问题的框架,并且AutoMapper允许我们根据自己的实际需求进行映射配置,使用起来较灵活。
1. 一对一映射
首先使用NuGet添加对AutoMapper的引用,然后创建两个类Human和Monkey
class Human { public string Name { set; get; } public int Age { set; get; } public string Country { set; get; } } class Monkey { public string Name { set; get; } public int Age { set; get; } }
现在我们进行Huamn实例和Monkey实例间的映射:
Monkey monkey = new Monkey() { Name = "monkey", Age = 100 }; //使用AutoMapper时要先进行初始化 Mapper.Initialize(cfg => cfg.CreateMap<Monkey, Human>() //我们可以根据实际需要来进行初始化,Monkey类没有Country属性 //这里我们给Human对象的Country属性指定一个值 .ForMember(h => h.Country, mce => mce.UseValue("china")) ); Human human = Mapper.Map<Human>(monkey); Console.WriteLine("姓名:{0},国籍:{1}", human.Name, human.Country);
程序运行结果:
可以看到,我们已经成功的将monkey对象的属性值映射到了human上。
2. 多对多映射
向对于一对一的映射而言,多对多的映射略显复杂。这里通过一个自定义类来封装具体的映射过程,代码如下:
static class EntityMapper { public static List<TDestination> Mapper<TDestination>(object[] source) where TDestination : class { if (source != null && source.Length > 0) { List<TDestination> results = new List<TDestination>(); foreach (var s in source) { results.Add(Mapper<TDestination>(s)); } if (results.Count > 0) { return results; } } return null; } public static TDestination Mapper<TDestination>(object source) where TDestination : class { Type sourceType = source.GetType(); Type destinationType = typeof(TDestination); AutoMapper.Mapper.Initialize(cfg => cfg.CreateMap(sourceType, destinationType)); var result = AutoMapper.Mapper.Map(source, sourceType, destinationType); return (TDestination)result; } }
执行映射:
1 Monkey[] monkeys = 2 { 3 new Monkey() {Name="monkey1",Age=1 }, 4 new Monkey() {Name="monkey2",Age=2 }, 5 new Monkey() {Name="monkey3",Age=3 }, 6 new Monkey() {Name="monkey4",Age=4 } 7 }; 8 9 List<Human> humans = EntityMapper.Mapper<Human>(monkeys); 10 11 foreach (var h in humans) 12 { 13 Console.WriteLine(h.Name); 14 }
程序运行结果:
这里虽然成功实现了映射,但无法给某个具体的human对象的Country属性赋值,若读者有更好的实现多对多映射的方式,望告知小编。
3. 多对一映射
1 Monkey monkey1 = new Monkey() { Name = "monkey1" }; 2 Mapper.Initialize(cof => cof.CreateMap<Monkey, Human>()); 3 Human human = Mapper.Map<Human>(monkey1); 4 5 Monkey monkey2 = new Monkey() { Age = 100 }; 6 Mapper.Initialize(cof => cof.CreateMap<Monkey, Human>() 7 .ForMember(h => h.Name, mc => mc.UseValue(human.Name)) 8 ); 9 human = Mapper.Map<Human>(monkey2); 10 11 Console.WriteLine("姓名:{0},年龄:{1}", human.Name, human.Age);
程序运行结果:
这里小编仅仅实现了二对一的映射,至于N对一的映射,小编未找到好的解决方案,若读者有好的解决方案,望告知小编,小编不胜感激。