简介
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;
网站获取更多信息。