如何使用Automapper将更改映射到现有集合()

知识的领域是无限的,我们的学习也是无限期的。这篇文章主要讲述如何使用Automapper将更改映射到现有集合?相关的知识,希望能为你提供帮助。
我有一些相当简单的代码,可以将viewmodel中集合的用户更改应用于模型中的集合。

public void Apply(ViewModelListItem source, ICollection< ModelListItem> dest) { //user added and removed an item before saving, do nothing if (source.Insert & & source.Delete) return; //user added an item if (source.Insert) { dest.Add(Mapper.Map< T> (source)); }//user deleted an item else if (source.Delete) { //Using custom Equals implementation that compares PK dest.Remove(dest.FirstOrDefault(destItem => source.Equals(destItem))); }//user modified or did not alter an item else { //Using custom Equals implementation that compares PK Mapper.Map(source, dest.FirstOrDefault(destItem => source.Equals(destItem))); } }

...
foreach (var item in MyViewModel.MyCollection) { Apply(item, MyModel.MyCollection); }

我在代码中的多个位置使用此模式,因此我一直在寻找以通用方式重用代码的方法。 Automapper是否可以简单地将引用传递给源/目标,让我在其上运行自己的设置逻辑?如果没有,有没有其他方法可以使这个代码通用,所以我不必为每个新的viewmodel写它?
答案我的解决方案
Viewmodel的基类:
public abstract class ListItemViewModel< T> { public bool Insert { get; set; } public bool Delete { get; set; }public abstract bool Equals(T model); public virtual void OnRemove(T model) { } public virtual void OnAdd(T model) { } public virtual void OnEdit(T model) { } }

辅助功能:
public static class MapConfiguration { public static void MapCollection< T> (IEnumerable< ListItemViewModel< T> > source, ICollection< T> dest) { foreach (var sourceItem in source) { //user added and removed an item before saving, do nothing if (sourceItem.Insert & & sourceItem.Delete) continue; //user added an item if (sourceItem.Insert) { var destItem = Mapper.Map< T> (sourceItem); sourceItem.OnAdd(destItem); dest.Add(destItem); }//user deleted an item else if (sourceItem.Delete) { //Using custom Equals implementation that compares PK var destItem = dest.First(d => sourceItem.Equals(d)); sourceItem.OnRemove(destItem); dest.Remove(destItem); }//user modified or did not alter an item else { //Using custom Equals implementation that compares PK var destItem = dest.First(d => sourceItem.Equals(d)); sourceItem.OnEdit(destItem); Mapper.Map(sourceItem, destItem); } } } }

实施:
  • 创建一个继承自ListItemViewModel的视图模型类,其中T是模型类型
  • 实现Equals(T model)方法,因此辅助函数可以匹配可枚举中的现有元素
  • 将ListItemViewModel的继承类型的通用可枚举属性添加到主视图模型中
配置automapper时,您现在可以使用以下内容:
.ForMember(m => m.MyList, opt => opt.Ignore()) .AfterMap((vm, m) => MapConfiguration.MapCollection(vm.MyList, m.MyList))

此代码将执行以下操作:
  • 如果设置了Insert标志,请将新项添加到集合中
  • 如果设置了Remove标志,则从集合中删除项目
  • 如果两个标志都未设置,则执行自动映射映射
另一答案看看AutoMapper.Collection。它自动处理集合上的所有CRUD操作:
【如何使用Automapper将更改映射到现有集合()】将根据源集合中集合的通用项类型与目标集合之间的用户定义等效性,从预先存在的集合对象添加/更新/删除项目

    推荐阅读