使用 AutoMapper 进行深度复制






2.31/5 (5投票s)
使用 AutoMapper 深拷贝对象。AutoMapper 是一个简单的库,旨在解决一个看似复杂的问题——消除将一个对象映射到另一个对象所需的代码。
引言
我在网上搜索,想找到深拷贝复杂对象的方法,发现了三种方法:
- 序列化
- 实现 ICloneable 接口
- 使用反射
由于我尝试克隆的复杂对象被整个团队使用,我不能对其进行任何修改。方法 1 和 2 对我不起作用。我不想使用反射。因此,我使用 Auto Mapper 来进行深拷贝。
背景
在应用程序中,我们有八种语言的产品信息。有些字段需要从英语语言获取,而其他字段需要从各自国际语言的产品中获取。因此,编写了一个类来映射可翻译的属性并创建国际语言产品。现在,当我们逐个将产品添加到产品列表中时,它会用最后添加的产品替换所有以前的语言产品。(复杂类型按引用传递)。因此,我使用 Automapper
来实现所需的功能。
什么是 AutoMapper?
AutoMapper
是一个简单的库,旨在解决一个看似复杂的问题——消除将一个对象映射到另一个对象所需的代码。有关更多信息,请访问 此链接。
Using the Code
请在您的应用程序中添加 AutoMapper
的 nuget 包。
我有一个复杂的类 Product
,如下所示
using System;
using System.Collections.Generic;
namespace DeepCloneWithAutoMapper.Models
{
[Serializable]
public class Product
{
public bool IsAvailable { get; set; }
public string Language { get; set; }
public int ProductId { get; set; }
public List<int> VariantIds { get; set; }
public List<int> SiteIds { get; set; }
public int MerretId { get; set; }
public string Name { get; set; }
public string CareDetails { get; set; }
public string AdditionalCopy { get; set; }
public string FabricConstruction { get; set; }
public string Materials { get; set; }
public string AdditionalInfo { get; set; }
public string Description { get; set; }
public int BrandId { get; set; }
public string BrandName { get; set; }
public string BrandDescription { get; set; }
public string CareInfo { get; set; }
public List<attribute> Attributes { get; set; }
public string DateModified { get; set; }
public string DateCreated { get; set; }
public string BackOfficeDateModified { get; set; }
public string ProductCode { get; set; }
public int CategoryId { get; set; }
public string Category { get; set; }
public int DepartmentId { get; set; }
public string Department { get; set; }
public int DivisionId { get; set; }
public string Division { get; set; }
public int ShippingRestrictionId { get; set; }
public bool IsReturnable { get; set; }
public string TranslatableDataDateChanged { get; set; }
public List<webcategory> WebCategories { get; set; }
public List<associatedproductgroup> AssociatedProductGroups { get; set; }
public int StatusId { get; set; }
}
}
虽然 Product
类是 Serializable
,但 WebCategories
和 AssociatedProductGroups
属性不是。
public List WebCategories { get; set; }
public List AssociatedProductGroups { get; set; }
请查找 WebCategory
和 AssociatedProductGroup
类。
//WebCategory
public class WebCategory
{
public int WebCategoryId { get; set; }
}
// AssociatedProductGroup
public class AssociatedProductGroup
{
public int AssociatedProductGroupId { get; set; }
public string Type { get; set; }
}
我有一个方法 "GetProductForAllLanguage
"。我希望通过映射可翻译的属性,将所有语言的产品存储在一个列表中。我调用 MapTranslatableProperties
方法来映射可翻译的属性并创建一个新的产品对象,然后将其添加到 List
中。但是,这会将 List
中的所有产品替换为最后添加的产品。因此,我使用 AutoMapper
进行深拷贝并创建一个新对象,然后将其添加到列表中。
public IEnumerable<Product> GetProductForAllLanguage() { var testProduct = new TestProduct(); var productList = new List<Product>(); productList.Add(testProduct.Product); productList.Add(testProduct.InternationalProduct); var internationalProduct = testProduct.InternationalProduct; internationalProduct.Language = "fr-Fr"; productList.Add(internationalProduct); internationalProduct = testProduct.InternationalProduct; internationalProduct.Language = "ru-RU"; productList.Add(internationalProduct); var feedProductsList = new List<Product>(); var defaultLanguageProduct = productList.FirstOrDefault(p => p.Language == "en-GB"); var otherLanguageProducts = productList.Where(s => s.Language != "en-GB"); feedProductsList.Add(defaultLanguageProduct); // this is how we initialize automapper with the same object type. Mapper.Initialize(cfg => { cfg.CreateMap<Product, Product>(); }); foreach (var product in otherLanguageProducts) { var feedProduct = new Product(); // map properties to give a new object. feedProduct = Mapper.Map(defaultLanguageProduct, feedProduct); feedProduct = MapTranslatableProperties(feedProduct, product); feedProductsList.Add(feedProduct); } return feedProductsList; }
关注点
我浪费了大量时间在网上搜索如何深拷贝对象,但只找到了上述三种方法。AutoMapper
只是突然出现在我的脑海中,我尝试了这段代码。我耍了个小聪明。如果您觉得这有帮助,请分享您的看法。
历史
- 2016 年 6 月 17 日:初始版本