返回首页

简介
AutoMapper是一个对象到对象的映射器,允许您解决问题具有相同的属性映射到另一个对象的另一种类型的一种类型的一个对象。例如,可以做一个沉重的实体Customer对象映射的CustomerDTO自动与AutoMapper。问题
你有没有过像这样写代码:

Customer customer = GetCustomerFromDB();



CustomerViewItem customerViewItem = new CustomerViewItem()

                           {

                               FirstName = customer.FirstName,

                               LastName = customer.LastName,

                               DateOfBirth = customer.DateOfBirth,

                               NumberOfOrders = customer.NumberOfOrders

                           };



ShowCustomerInDataGrid(customerViewItem);

一个示例场景可能是:
我们有我们的域模型,其中有一个客户实体,我们将显示在DataGrid中的客户,为此,我们需要轻得多的对象CustomerViewItem,这是一个网格绑定到一个列表。
正如您所看到的,也有四行代码,这仅仅复制从一个对象到另一个值。它也可以,你将需要10-15列在您的网格显示。怎么办呢?
你想有一些会做映射自动从客户的CustomerViewItem的呢?
当然,你这样做,特别是如果你有像映射到DTO的对象,这被认为是虽然线路发送大量的数据对象的另一种情况。AutoMapper(解决方案)
,我们可以看到,quot; AutoMapper是对象的对象映射器。对象对象映射的工作原理是一个不同类型的输出对象转化为一种类型的输入对象。是什么让AutoMapper有趣的是,它提供了一些有趣的公约采取肮脏的工作,找出如何映射类型一个类型B.只要B型如下AutoMapper的建立公约,几乎是零配置需要映射两个types.quot ;所以,换句话说,它提供了解决我们的问题。入门
要开始,去下载。它是一个独立的组件,所以你不应该包括在您的项目的参考给它的困难。
以问AutoMapper做肮脏的工作,而不是我,我们需要在我们的代码执行开始添加此行的地方:
一旦我们有,我们正在做,我们可以使用此代码,让我们的映射对象:
Customer customer = GetCustomerFromDB();



CustomerViewItem customerViewItem = 

   Mapper.Map<Customer, CustomerViewItem>(customer);



ShowCustomerInDataGrid(customerViewItem);

让我们在整个​​代码库一看,看到所有关于我什么都谈进一步:
class Program

{

    static void Main(string[] args)

    {

        var program = new Program();

        Mapper.CreateMap<Customer, CustomerViewItem>();

        program.Run();

    }



    private void Run()

    {

        Customer customer = GetCustomerFromDB();



        CustomerViewItem customerViewItem = 

          Mapper.Map<Customer, CustomerViewItem>(customer);



        ShowCustomerInDataGrid(customerViewItem);

    }



    private void ShowCustomerInDataGrid(

                   CustomerViewItem customerViewItem){}



    private Customer GetCustomerFromDB()

    {

        return new Customer()

        {

            DateOfBirth = new DateTime(1987, 11, 2),

            FirstName = "Andriy",

            LastName = "Buday",

            NumberOfOrders = 7

        };

    }

}



public class Customer

{

    public string FirstName { get; set; }

    public string LastName { get; set; }

    public DateTime DateOfBirth { get; set; }



    public int NumberOfOrders { get; set; }

}



public class CustomerViewItem

{

    public string FirstName { get; set; }

    public string LastName { get; set; }

    public DateTime DateOfBirth { get; set; }



    public int NumberOfOrders { get; set; }

}

,并证明已映射的所有值,看看这幅画:{S0}更复杂的例子1(自定义地图)
到目前为止,我们知道所有有关做一个非常简单的映射的。但是,如果我们需要更复杂的东西,例如,的,CustomerViewItem应该有真实姓名,包括对客户的第一个和最后一个名称?后我增加公共字符串的FullName
{获取;设置;} CustomerViewItem和我在调试模式下运行应用程序,我得到一个空的财产。这是很好的,而且是因为AutoMapper没有看到任何Customer类的FullName属性。为了quot;打开它eyesquot;,所有你需要做的的是改变我们的CreateMap过程有点:
Mapper.CreateMap<Customer, CustomerViewItem>()

    .ForMember(cv => cv.FullName, m => m.MapFrom(

    s => s.FirstName + " " + s.LastName))

和结果立即得到:{S1}更复杂的例子2(压扁)
如果你的公司类型的属性公司:
public class Customer

{

    public Company Company { get; set; }

    //...

}



public class Company

{

    public string Name { get; set; }

}

和希望映射到视图类的公司名称:
public class CustomerViewItem

{

    public string CompanyName { get; set; }

    //...

}

你需要改变你的映射,使这项工作?
答:没有。 AutoMapper类的深度,如果名称匹配,它会为你做的映射。更复杂的例子3(自定义类型解析器)
如果你有一个布尔属性,在您的客户类贵宾?
public class Customer

{

    public bool VIP { get; set; }

}

要映射到字符串VIP像quot代表; Yquot;或"Nquot,而是?
public class CustomerViewItem

{

    public string VIP { get; set; }

}

好了,我们可以解决这个我们没有的FullName以同样的方式,但一个更合适的方法是使用自定义的解析器。所以,让我们创建一个客户解析器将解决为我们的贵宾问题。
它看起来像:
public class VIPResolver : ValueResolver<bool, string>

{

    protected override string ResolveCore(bool source)

    {

        return source ? "Y" : "N";

    }

}

,只有一条线是需要我们CreateMap过程:
.ForMember(cv => cv.VIP, m => m.ResolveUsing<VIPResolver>().FromMember(x => x.VIP));
更复杂的例子(自定义格式化)
如果我想AutoMapper使用我自定义格式的DateTime,而不是仅仅使用ToString,当它从一个String属性的DateTime的映射?比方说,我想使用ToLongDateString的方法来显示的出生日期,在不同的时尚。
,我们添加:
public class DateFormatter:IValueFormatter

{

    public string FormatValue(ResolutionContext context)

    {

        return ((DateTime) context.SourceValue).ToLongDateString();

    }

}

和确保AutoMapper知道在哪里使用它:
.ForMember(cv => cv.DateOfBirth, m => m.AddFormatter<DateFormatter>());

所以现在,我已经有了:{S2}
太好了,是不是?出生日期,甚至是我的母语。性能问题
我张贴这篇文章后,一个人是真的关心AutoMapper性能。所以,我决定来衡量AutoMapper映射和手动映射代码的执行时间。
首先,我有代码,返回我10万几乎是随机的客户到客户的名单。AutoMapper映射时间的测量:手动映射时间的测量:
stopwatch.Start();

var manualCVI = new List<customerviewitem>();

foreach (var customer in customers)

{

        var customerViewItem = new CustomerViewItem()

		{

                     	FirstName = customer.FirstName,

                    	LastName = customer.LastName,

                 		FullName = customer.LastName + " " + customer.FirstName,

          		DateOfBirth = customer.DateOfBirth.ToLongDateString(),

           		CompanyName = customer.Company.Name,

              		NumberOfOrders = customer.NumberOfOrders,

           		VIP = customer.VIP ? "Y" : "N"

		};

        manualCVI.Add(customerViewItem);

}



stopwatch.Stop();            

Console.WriteLine(string.Format("Manual Mapping: {0}", stopwatch.ElapsedMilliseconds));

我跑了很多次我的测试和可能的产出之一可能是:
AutoMapper: 2117

Manual Mapping: 293

它看起来像手动映射是不是自动快7倍。但是,嘿,花了2秒地图百成千上万的客户。
的情况下,你应该决定是否表现是如此重要,为您或没有之一。我不认为有很多情况下,当你真的需要选择手动映射,正是因为性能问题。兴趣点
我希望我的文章是有趣的阅读,它给你的想法如何,你可以利用这个新功能称为quot; AutoMapperquot;
网站获取更多信息。

回答

评论会员:游客 时间:2012/01/25
sekhar空运的:这很好地解释了AutoMapper概念,我很欣赏,但我想下来一周的每一天的手中,而写更多的代码,如果在更快的性能,它的结果。为什么要我们牺牲用户的体验只是使我可以得到返回到Lifehacker的一个小越早
?Sunasara Imdadhusen
评论会员:游客 时间:2012/01/25
我是用的这得到了之一出手清除概念混淆
Sunasara Imdadhusen
评论会员:游客 时间:2012/01/25
我想比较GUID下面的代码。可以指导我写检查的GUID功能的关键(GUID)的剂量,如果目标表不存在,那么它将返回虚假其他真实的。codeprelang="cs"spanclass="code-comment"///spanspanclass="code-comment"HereiwouldliketoaddcodeforcheckingGUIDisexistsornot?/spanspanclass="code-keyword"public/spanspanclass="code-keyword"class/spanVIPResolver:ValueResolver<spanclass="code-keyword"bool/span,spanclass="code-keyword"string/span>{spanclass="code-keyword"protected/spanspanclass="code-keyword"override/spanspanclass="code-keyword"string/spanResolveCore(spanclass="code-keyword"bool/spansource){spanclass="code-keyword"return/spansource?spanclass="code-string""/spanspanclass="code-string"Y"/span:spanclass="code-string""/spanspanclass="code-string"N"/span;}}/pre/code,ImdadhusensunaSaRaImdadhusen919909544184
Ekta梅塔
评论会员:游客 时间:2012/01/25
出色的工作,你没有。非常感谢您。特别定制的解析器。我是非常有用的。我的投票5sunaSaRaImdadhusen919909544184
Berlus
评论会员:游客 时间:2012/01/25
好文章结合实例。感谢
舍甫琴科Buday
评论会员:游客 时间:2012/01/25
?如果没有你有任何好处berlus
米洛斯托米奇
评论会员:游客 时间:2012/01/25
我看到后imgsrc=]它有可能使用框架2.0AutoMapper,但你有没有C#3.0中表达了很多疼痛书面映射建设我不熟悉其他映射器,但我认为,这里{A5}]你可以找到一些问题的信息
马特Sollars
评论会员:游客 时间:2012/01/25
我相信的反映,是用在这里的表现来看。两年前,我看到了这里一个解决方案,在CodeProject在运行时使用排放生产任何给定的类型是手动复制一样快的映射器类。但不幸的是,我无法找到该文章更多。谁能帮我找到它的
?aemami99
评论会员:游客 时间:2012/01/25
米洛斯,我没有用过发出映射,但我相信这是你在找什么。{A6}这里的{A7}]马特{A8}
舍甫琴科Buday
评论会员:游客 时间:2012/01/25
大文章-我不知道这个库,但它是非常有用的
史蒂夫汉森
评论会员:感谢很多 时间:2012/01/25
舍甫琴科Buday: |这一切首先看起来很酷,但LT; TGT;部分,这使得它看起来很奇怪的代码样本中缺少。 Map.CreateMap(){S3}
评论会员:舍甫琴科Buday 时间:2012/01/25
是...我明白了,感谢。我有我的博客上的文章和一些复制粘贴的问题我已经失去了部分
在更新的文章
进程眼下