C# 如何在automapper中展平列表中的条件对象
我有一个C# 如何在automapper中展平列表中的条件对象,c#,automapper,automapper-3,C#,Automapper,Automapper 3,我有一个项,其中包含一个产品的列表,这些产品使用自动映射器映射到各自的视图模型对象 在我的MVC项目中,我有一个动作方法,它显示一个带有所选产品的项目。为此,我有一个名为itemtailsviewmodel的ViewModel视图模型,其中包含展开的项对象、一个产品视图模型列表和一个展开的选定产品 我遇到的困难是最好地展示这个选定的产品 想象一下eBay,你有一个物品,你可以选择多种不同的物品,例如颜色。对我来说,多种变体是产品。当用户选择产品时,我想返回项目详细信息,即项目,产品列表和所选的产
项
,其中包含一个产品的列表,这些产品使用自动映射器映射到各自的视图模型
对象
在我的MVC项目中,我有一个动作方法,它显示一个带有所选产品的项目。为此,我有一个名为itemtailsviewmodel
的ViewModel
视图模型,其中包含展开的项
对象、一个产品视图模型
列表和一个展开的选定产品
我遇到的困难是最好地展示这个选定的产品
想象一下eBay,你有一个物品
,你可以选择多种不同的物品,例如颜色。对我来说,多种变体是产品
。当用户选择产品
时,我想返回项目详细信息
,即项目
,产品列表
和所选的产品
我想知道最好的方法是什么?目前,我的方法是将一个项目映射到一个项目细节视图模型
,选择所需的产品视图模型
,然后专门将产品视图模型
的每个属性映射回项目细节视图模型
。此外,由于项目
和产品
具有相同的命名属性,映射产品的最后一行将覆盖项目
的id和代码
关于如何最好地配置映射,有什么建议吗
我省略了现有的映射,因为除了将选定的ProductViewModel
映射回itemdailsviewmodel
之外,它主要是一对一的直接映射
Mapper.CreateMap<Item, ItemViewModel>()
.ReverseMap();
Mapper.CreateMap<ProductViewModel, ItemDetailsViewModel>()
.ForMember(d => d.ProductId, o => o.MapFrom(s => s.Id))
.ForMember(d => d.ProductCode, o => o.MapFrom(s => s.Code));
Mapper.CreateMap()
.ReverseMap();
Mapper.CreateMap()
.ForMember(d=>d.ProductId,o=>o.MapFrom(s=>s.Id))
.ForMember(d=>d.ProductCode,o=>o.MapFrom(s=>s.Code));
课程
public class Item
{
public int Id { get; set; }
public string Code { get; set; }
public IList<Product> Products { get; set; }
}
public class Product
{
public int Id { get; set; }
public string Code { get; set; }
}
public class ItemViewModel
{
public int Id { get; set; }
public string Code { get; set; }
public IList<ProductViewModel> Products { get; set; }
}
public class ItemDetailsViewModel : ItemViewModel
{
public int ProductId;
public string ProductCode;
}
public class ProductViewModel
{
public int Id { get; set; }
public string Code { get; set; }
}
公共类项目
{
公共int Id{get;set;}
公共字符串代码{get;set;}
公共IList产品{get;set;}
}
公共类产品
{
公共int Id{get;set;}
公共字符串代码{get;set;}
}
公共类ItemViewModel
{
公共int Id{get;set;}
公共字符串代码{get;set;}
公共IList产品{get;set;}
}
公共类ItemDetailsViewModel:ItemViewModel
{
公共int ProductId;
公共字符串代码;
}
公共类ProductViewModel
{
公共int Id{get;set;}
公共字符串代码{get;set;}
}
行动
public ActionResult ItemDetails()
{
var item = new Item
{
Id = 1,
Code = "Item1",
Products = new List<Product>()
{
new Product { Id = 1, Code = "Product1" },
new Product { Id = 2, Code = "Product2" },
new Product { Id = 3, Code = "Product3" },
}
};
var productCode = "Product2";
var itemDetailsViewModel = Mapper.Map<ItemDetailsViewModel>(item);
if (itemDetailsViewModel.Products != null && itemDetailsViewModel.Products.Count > 0)
{
ProductViewModel productViewModel = null;
if (!String.IsNullOrEmpty(productCode))
productViewModel = itemViewModel.Products.FirstOrDefault(e => e.Code.Equals(productCode, StringComparison.OrdinalIgnoreCase));
if (productViewModel == null)
productViewModel = itemViewModel.Products[0];
Mapper.Map<ProductViewModel, ItemDetailsViewModel>(productViewModel, itemDetailsViewModel);
}
}
public ActionResult ItemDetails()
{
var项目=新项目
{
Id=1,
Code=“Item1”,
产品=新列表()
{
新产品{Id=1,Code=“Product1”},
新产品{Id=2,Code=“Product2”},
新产品{Id=3,Code=“Product3”},
}
};
var productCode=“Product2”;
var itemtailsviewmodel=Mapper.Map(item);
if(itemDetailsViewModel.Products!=null&&itemDetailsViewModel.Products.Count>0)
{
ProductViewModel ProductViewModel=null;
如果(!String.IsNullOrEmpty(productCode))
productViewModel=itemViewModel.Products.FirstOrDefault(e=>e.Code.Equals(productCode,StringComparison.OrdinalIgnoreCase));
if(productViewModel==null)
productViewModel=itemViewModel.Products[0];
Map(productViewModel、itemDetailsViewModel);
}
}
一种解决方案是在从ProductViewModel
到ItemDetailsViewModel
的映射中忽略ItemDetailsViewModel
中的属性:
Mapper.CreateMap<ProductViewModel, ItemDetailsViewModel>()
.ForMember(d => d.Id, opt => opt.Ignore())
.ForMember(d => d.Code, opt => opt.Ignore())
.ForMember(d => d.ProductId, o => o.MapFrom(s => s.Id))
.ForMember(d => d.ProductCode, o => o.MapFrom(s => s.Code));
Mapper.CreateMap()
.ForMember(d=>d.Id,opt=>opt.Ignore())
.ForMember(d=>d.Code,opt=>opt.Ignore())
.ForMember(d=>d.ProductId,o=>o.MapFrom(s=>s.Id))
.ForMember(d=>d.ProductCode,o=>o.MapFrom(s=>s.Code));
对于忽略目标类型中不存在的属性的扩展方法,您可以看到以下答案:@Marshall777:不确定这是否适用于此处--在这种情况下,目标类型上确实存在属性,这就是问题所在。请尝试一下。有没有关于如何改进的建议?似乎我正在编写/维护很多“从这个到那个”的代码。也许这就是我实现的方式。在某种程度上,这是使用viewmodels的一部分,至少在我的经验中是这样。不过,我会继续考虑其他解决方案。