首页
学习
活动
专区
工具
TVP
发布
社区首页 >问答首页 >使用AutoMapper映射只读子集合

使用AutoMapper映射只读子集合
EN

Stack Overflow用户
提问于 2011-11-08 13:45:32
回答 2查看 3.4K关注 0票数 19

这不是一个问题,因为我已经找到了一种方法来做我想做的事情,但似乎应该有更好的方法来做这件事。我到处都找过了,什么也没找到。

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

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);
    }
}

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

(为了清楚起见,我省略了与问题无关的属性以及错误检查和保护...)

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实例列表。

然而,当以另一种方式映射回来时,域模型上的集合并没有被设置--因为它显然是只读的。似乎没有任何方法可以使用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持久化的,因此我不得不担心这一点。但是,一次只做一件事。:)

希望这能帮助其他遇到同样问题的人,也许已经正确解决了这个问题的人能够纠正我。

EN

回答 2

Stack Overflow用户

发布于 2018-03-18 01:06:53

我不喜欢在属性getter或setter中包含逻辑,但是如何将setter添加到父类的Children属性中呢

public class Parent
{
    private readonly IList<Child> _children = new List<Child>();

    public IEnumerable<Child> Children
    {
        get => _children;
        set => AddChildren(value);
    }

    public void AddChild(Child child)
    {
        child.Parent = this;
        _children.Add(child);
    }

    private void AddChildren(IEnumerable<Child> children)
    {
        _children.Clear();

        foreach (var child in children)
        {
            AddChild(child);
        }
    }
}

并且AfterMap逻辑并不是更必要的。映射配置将非常简单

Mapper.CreateMap<ParentDTO, Parent>();
票数 3
EN

Stack Overflow用户

发布于 2012-06-22 20:30:38

我认为如果你打算出于良好的业务逻辑原因来保护属性,那么如果AutoMapper在进行映射时绕过它们,那将是不好的。在这种情况下,我倾向于放弃流畅的语法,将创建逻辑放在自己的方法中,如下所示:

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

然后:

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

我发现这比有很多忽略声明更容易遵循。

票数 0
EN
页面原文内容由Stack Overflow提供。腾讯云小微IT领域专用引擎提供翻译支持
原文链接:

https://stackoverflow.com/questions/8046442

复制
相关文章

相似问题

领券
问题归档专栏文章快讯文章归档关键词归档开发者手册归档开发者手册 Section 归档