AutoMapper语言 - 在使用ReverseMap()进行反向映射时,包含/替换源列表中的单个项目



我的当前地图:

CreateMap<Item, ItemDetailsViewModel>()
.ForMember(x => x.ActiveChildItem, d => d.MapFrom(z => z.ChildItems.FirstOrDefault(f => f.IsActive)))
.ReverseMap()
.ForMember(x => x.ChildItems, d => /*How I can find and replace item in source list 
items(ChildItems) to ActiveChildItem?*/)

将单个物品映射到物品集合的最佳方法是什么?
我不想在我的视图模型中使用集合…

从技术上讲,这不是映射操作。当属性映射完成后,您应该执行此操作。

使用AfterMap方法-

CreateMap<Item, ItemDetailsViewModel>()
.ForMember(x => x.ActiveChildItem, d => d.MapFrom(z => z.ChildItems.FirstOrDefault(f => f.IsActive)))
.ReverseMap()
.AfterMap((s, d) =>
{
// add or find-and-replace child item here
});

CreateMap<Item, ItemDetailsViewModel>()
.ForMember(x => x.ActiveChildItem, d => d.MapFrom(z => z.ChildItems.FirstOrDefault(f => f.IsActive)))
.ReverseMap()
.AfterMap<MyCoolAction>();

其中MyCoolActionIMappingAction的实现,如-

public class MyCoolAction : IMappingAction<ItemVM, Item>
{
public void Process(ItemVM source, Item destination, ResolutionContext context)
{
// add or find-and-replace child item here
}
}

更多信息,请查看文档-前后映射操作

有一个完整的示例将使帮助您更容易。还有一点你们没有考虑到。

当从单个项映射回集合时会发生什么?是否应该将该集合替换为包含单个项目的新集合?应该修改现有的列表,如果您修改了列表,但是在模型列表中找不到视图模型项,会发生什么?应该添加吗?

所以,撇开这些悬而未决的问题不谈,下面是一个关于如何替换整个列表的示例。

如果您需要不同的行为,请查看最后一个CreateMap()方法。第三个参数dest指向目标对象的当前属性值。它包含了模型列表。您可以根据需要操作现有的dest列表,而不是返回一个值(就像我对新列表所做的那样)。

using System;
using System.Collections.Generic;
using System.Linq;
using AutoMapper;
namespace ConsoleApp
{
public static class Program
{
public static void Main()
{
var config = new MapperConfiguration(conf => conf.AddProfile<MyProfile>());
var mapper = config.CreateMapper();
var model = new Model { Items = new[] { new ModelItem { Name = "NotActive Item", IsActive = false }, new ModelItem { Name = "Active Item", IsActive = true } } };
var viewModel = mapper.Map<ViewModel>(model);
var newModel = mapper.Map<Model>(viewModel);
Console.WriteLine(viewModel.ActiveItem.Name);
Console.WriteLine(newModel.Items.Count);
Console.WriteLine(newModel.Items.First().Name);
Console.WriteLine(newModel.Items.First().IsActive);
}
}
public class MyProfile : Profile
{
public MyProfile()
{
CreateMap<ModelItem, ViewModelItem>();
CreateMap<Model, ViewModel>()
.ForMember(view => view.ActiveItem, conf => conf.MapFrom(model => model.Items.FirstOrDefault(item => item.IsActive)));
CreateMap<ViewModelItem, ModelItem>().ForMember(item => item.IsActive, conf => conf.MapFrom(_ => true));
CreateMap<ViewModel, Model>()
.ForMember(model => model.Items, conf => conf.MapFrom((view, model, dest, context) => view.ActiveItem == null
                              ? Array.Empty<ModelItem>()
                              : new[] { context.Mapper.Map<ModelItem>(view.ActiveItem) }));
}
}
public class Model
{
public IReadOnlyList<ModelItem> Items { get; set; }
}
public class ModelItem
{
public string Name { get; set; }
public bool IsActive { get; set; }
}
public class ViewModel
{
public ViewModelItem ActiveItem { get; set; }
}

public class ViewModelItem
{
public string Name { get; set; }
}
}

最新更新