使用AutoMapper进行对象间映射

在开发过程中,难免遇到下面这种情况:两个(或多个)对象所拥有的大多数属性是重复的,我们需要在对象间进行映射(即将一个对象的属性值赋给另一个对象。通常我们可以进行如下操作:

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对一的映射,小编未找到好的解决方案,若读者有好的解决方案,望告知小编,小编不胜感激。

版权声明

本文为作者原创,版权归作者雪飞鸿所有。 转载必须保留文章的完整性,且在页面明显位置处标明原文链接

如有问题, 请发送邮件和作者联系。

本文参与腾讯云自媒体分享计划,欢迎正在阅读的你也加入,一起分享。

发表于

我来说两句

0 条评论
登录 后参与评论

相关文章

来自专栏风口上的猪的文章

.NET面试题系列[13] - LINQ to Object

"C# 3.0所有特性的提出都是更好地为LINQ服务的" - Learning Hard

12420
来自专栏java架构师

Stream篇(1)

最近在看一个写的很好的博客,为了加深记忆,把自认为重要的东西,一边看,一边记在这里 一、什么是流、字节序列、字节 一条河中有一条鱼游过,这条鱼就是一个字节,这个...

31070
来自专栏数据结构与算法

BZOJ4260: Codechef REBXOR (01Tire树)

10930
来自专栏JadePeng的技术博客

C# 词典数据结构设计【附demo】

分析 要建立词典,最基本的应该有词典的描述信息、词典索引文件以及词典数据文件。 /// <summary> /// 索引文件 /// </summary>...

36540
来自专栏IMWeb前端团队

Redux源码解析系列(四)-- combineReducers

本文作者:IMWeb 黄qiong 原文出处:IMWeb社区 未经同意,禁止转载 combindeReducer 字面意思就是用来合并reducer的...

20270
来自专栏菩提树下的杨过

温故而知新:c#中的特性(attribute)

特性(Attribute)是微软在.Net中自创的一种新技术,对于很多初学者来讲,特性一直是一块难啃的骨头。 既然弄不懂,那我们就暂时绕过它吧,回想一下我们在写...

20990
来自专栏MasiMaro 的技术博文

windows 纤程

纤程本质上也是线程,是多任务系统的一部分,纤程为一个线程准并行方式调用多个不同函数提供了一种可能,它本身可以作为一种轻量级的线程使用。它与线程在本质上没有区别,...

17920
来自专栏小樱的经验随笔

Codeforces 706B Interesting drink

B. Interesting drink time limit per test:2 seconds memory limit per test:256 meg...

30480
来自专栏个人分享

Hive metastore整体代码分析及详解

  从上一篇对Hive metastore表结构的简要分析中,我再根据数据设计的实体对象,再进行整个代码结构的总结。那么我们先打开metadata的目录,其目录...

69430
来自专栏MasiMaro 的技术博文

windows错误处理

在调用windows API时函数会首先对我们传入的参数进行校验,然后执行,如果出现什么情况导致函数执行出错,有的函数可以通过返回值来判断函数是否出错,比如对于...

14420

扫码关注云+社区

领取腾讯云代金券