使用AutoMapper映射只读子集合 [英] Mapping readonly child collection with AutoMapper

查看:149
本文介绍了使用AutoMapper映射只读子集合的处理方法,对大家解决问题具有一定的参考价值,需要的朋友们下面随着小编来一起学习吧!

问题描述

这不是一个问题,因为我找到了一种方式来做我想要的,但似乎应该有一个更好的方法来做。我已经搜索到处,没有找到任何东西。



基本上,我有一个非常标准的对象模型。

  public class Parent 
{
private readonly IList< Child> _children = new List< Child>();
public IEnumerable public void AddChild(Child child)
{
child.Parent = this;
_children.Add(child);
}
}

  public class Child 
{
public Parent Parent {get;组; }
}

(我忽略了与问题无关的属性和错误检查和保护,以便清楚...)

  public class ParentDTO 
{
List< ChildDTO> Children = new List< ChildDTO>();
}

  public class ChildDTO 
{
}

我使用一个方法向集合添加子元素的原因是为了保持对添加子元素时需要处理的业务逻辑的控制。



标准映射:

  Mapper.CreateMap< Parent,ParentDTO>(); 
Mapper.CreateMap< ParentDTO,Parent>();
Mapper.CreateMap< Child,ChildDTO>();
Mapper.CreateMap< ChildDTO,Child>();

似乎从服务层工作得很好。域对象的子对象完全映射到 ChildDTO 实例的列表。



然而,当映射回另一个方式,领域模型上的集合没有设置 - 因为它是readonly,显然。似乎没有任何方法使用AutoMapper直接设置私有字段。我尝试了在这里和互联网的其他部分找到的各种建议。



最后,我想出了以下映射:

  Mapper.CreateMap< ParentDTO,Parent>()
.ForMember(m => m.Children,o => o.Ignore ))
.AfterMap((s,d)=>
{
foreach(var c in s.Children)
d.AddChild(Mapper.Map< ChildDTO,Child> ;(c));
});

这是我需要的。然而,我不能帮助感觉有一个更好的方式,我没有测试这个与现有的父,有孩子修改,可能添加和删除,所以我知道它实际上是不正确的。最终,这个域模型是使用NHibernate持久化的,所以我必须担心。但是,一次有一件事。 :)



希望这可能会帮助遇到相同问题的其他人,也许正确解决问题的人将能够纠正我。

$ b $我想如果你要保护属性的良好的业务逻辑的原因,那么它将是坏的,如果AutoMapper规避他们在做映射时。在这种情况下,我宁愿放弃流利的语法,并将创建逻辑放在自己的方法中,如下:

  private Parent MapParentDTOToParent (ParentDTO源)
{
var parent = new Parent();
//业务逻辑
return父
}

然后:

  Mapper.CreateMap< ParentDTO,Parent>()。ConvertUsing(MapParentDTOToParent); 

我发现这比跟很多忽略声明更容易。


It's not so much a question, as I have found a way to do what I want, but it seems like there should be a better way to do it. I've searched everywhere and not found anything.

Basically, I have what I consider a very standard object model.

public class Parent
{
    private readonly IList<Child> _children = new List<Child>();
    public IEnumerable<Child> Children { get { return _children; } }
    public void AddChild(Child child)
    {
        child.Parent = this;
        _children.Add(child);
    }
}

and

public class Child
{
    public Parent Parent { get; set; }
}

(I've omitted properties irrelevant to the problem and error checking and guarding for the sake of clarity...)

public class ParentDTO
{
    List<ChildDTO> Children = new List<ChildDTO>();
}

and

public class ChildDTO
{
}

The reason I'm using a method to add children to the collection is to maintain control of business logic that needs to be processed when a child is added.

With the standard mapping of:

Mapper.CreateMap<Parent, ParentDTO>();
Mapper.CreateMap<ParentDTO, Parent>();
Mapper.CreateMap<Child, ChildDTO>();
Mapper.CreateMap<ChildDTO, Child>();

It seems to work fine coming from the service layer. The children of the domain object map perfectly to the list of ChildDTO instances.

However, when mapping back the other way, the collection on the domain model isn't set - because it's readonly, obviously. There doesn't appear to be any way to directly set the private field using AutoMapper. I have tried various suggestions found on here, and other parts of the internet.

In the end, I came up with the following mapping:

Mapper.CreateMap<ParentDTO, Parent>()
    .ForMember(m => m.Children, o => o.Ignore())
    .AfterMap((s, d) =>
                        {
                            foreach(var c in s.Children)
                                d.AddChild(Mapper.Map<ChildDTO, Child>(c));
                        });

This works as I required. However, I can't help feeling that there has to be a better way, and I haven't tested this with an existing parent that's had children modified and maybe added and removed, so I know it's not actually correct yet. Ultimately, this domain model is persisted using NHibernate, so I do have to worry about that. But, one thing at a time. :)

Hopefully this might help someone else who's encountering the same problem, and maybe someone who's solved it properly will be able to correct me.

解决方案

I think if you are going to protect properties for good business logic reasons then it would be bad if AutoMapper circumvented them when doing its mapping. In situations like this I prefer to abandon the fluent syntax and place the creation logic in its own method like this:

private Parent MapParentDTOToParent(ParentDTO source)
{
    var parent = new Parent();
    // Business logic here
    return parent
}

and then:

Mapper.CreateMap<ParentDTO, Parent>().ConvertUsing(MapParentDTOToParent);

I find this easier to follow than having lots of ignore declarations.

这篇关于使用AutoMapper映射只读子集合的文章就介绍到这了,希望我们推荐的答案对大家有所帮助,也希望大家多多支持IT屋!

查看全文
登录 关闭
扫码关注1秒登录
发送“验证码”获取 | 15天全站免登陆