在视图模型中映射子集合

本文关键字:映射 子集合 模型 视图 | 更新日期: 2023-09-27 18:15:57

我有一个视图模型,需要显示特定的IEnumerable字段作为分号分隔的文本框。起初我想到使用DefaultModelBinder来转换它,但我有困难思考如何实现它在两个方向(dto <-> viewmodel)。

别名是我试图显示为一个用分号分隔的文本框的字段。

public class Parent
{
    public IEnumerable<Child> Children { get; set; }
}
public class Child
{
    public IEnumerable<string> Nicknames { get; set; }
}

所以我决定尝试AutoMapper,我创建了两个ViewModels:

public class ParentViewModel
{
    public IEnumerable<ChildViewModel> Children { get; set; }
}
public class ChildViewModel
{
    public string Nicknames { get; set; }
}

然后,我创建映射,就像这样为子节点创建映射(为简洁起见,省略了反向转换)

Mapper.CreateMap<Child, ChildViewModel>().ForMember(
d => d.Nicknames, o => o.ResolveUsing<ListToStringConverter>().FromMember(s => s.Nicknames);

然后,为父节点创建一个朴素映射(同样,省略了另一种方式)

Mapper.CreateMap<Parent, ParentViewModel>();

我真的希望孩子映射自动发生,但他们没有,我已经创建了太多的"适当"的代码来解决一个非常简单的问题,在任何其他更简单/旧的非mvc环境中,我很久以前就完成了:)我怎么能继续并告诉AutoMapper转换孩子而不写另一个"孩子成员解析器"。

我是不是想多了,有更简单的方法吗?

谢谢!

在视图模型中映射子集合

try

Mapper.CreateMap<Parent, ParentViewModel>();
Mapper.CreateMap<Child, ChildViewModel>();
var v = Mapper.Map<Parent, ParentViewModel>(parent);

找到了这个解决方案https://stackoverflow.com/a/7555977/1586498,这对我来说很有效:

Mapper.CreateMap<ParentDto, Parent>()
  .ForMember(m => m.Children, o => o.Ignore()) // To avoid automapping attempt
  .AfterMap((p,o) => { o.Children = ToISet<ChildDto, Child>(p.Children); });

ToISet函数在上面的链接中定义。

更简单的例子在LinqPad 'just work' -所以需要更多的调查。

工作程序的完整列表:

    public class Child{ public string Name  {get; set; }}
    public class ChildDto{  public string NickName {get; set; }}
    public class Parent{    public virtual IEnumerable<Child> Children  {get; set; }}
    public class ParentDto{ public IEnumerable<ChildDto> Kids  {get; set; }}
    private static void Main()
    {
        AutoMapper.Mapper.CreateMap<Parent, ParentDto>().ForMember(d=>d.Kids, opt=>opt.MapFrom(src=>src.Children));
        AutoMapper.Mapper.CreateMap<Child, ChildDto>().ForMember(d=>d.NickName, opt=>opt.MapFrom(src=>src.Name));
        var pList = new HashSet<Parent>{
            new Parent{ Children = new HashSet<Child>{new Child{Name="1"}, new Child{Name="2"}}},
            new Parent{ Children = new HashSet<Child>{new Child{Name="3"}, new Child{Name="4"}}},
        };
        var parentVm = AutoMapper.Mapper.Map<IEnumerable<Parent>, IEnumerable<ParentDto>>(pList);
        parentVm.Dump();    
    }