映射子对象时,AutoMapper传递父引用 [英] AutoMapper pass parent reference when mapping child object

查看:126
本文介绍了映射子对象时,AutoMapper传递父引用的处理方法,对大家解决问题具有一定的参考价值,需要的朋友们下面随着小编来一起学习吧!

问题描述

我正在尝试使用AutoMapper将从Web服务接收到的某些DTO(数据协定)对象映射到我的业务对象中.根DTO对象包含子对象的集合.我的业务对象还具有子业务对象的子级集合.为了使AutoMapper正常工作,我必须在业务对象的collection属性中包含一个setter,否则该collection始终为空.另外,我必须向集合类型添加一个默认的构造函数.因此,在我看来,AutoMapper正在实例化一个新的集合对象,将其填充并设置为我的业务对象的collection属性.

I am trying to use AutoMapper to map some DTO (data contract) objects received from a web service into my business objects. The root DTO object contains a collection of child objects. My business object also has a child collection of child business objects. In order to get AutoMapper to work, I had to include a setter on the collection property in my business object or the collection would always be empty. In addition, I had to add a default constructor to the collection type. So, it appears to me that AutoMapper is instantiating a new collection object, populating it and setting as the collection property of my business object.

虽然这一切都很好,但我有其他逻辑,在创建集合时必须将其连接起来,并且使用默认构造函数无法达到目的.本质上,我正在建立亲子关系并整理一些事件,使事件从孩子到父母冒泡.

While this is all well and good, I have additional logic that has to be wired up when the collection is created and having the default constructor defeats the purpose. Essentially, I am establishing the parent-child relationship and wiring up some events so they bubble from child to parent.

我想做的是让AutoMapper简单地将DTO集合中的子对象映射到我的BO上的现有集合.换句话说,跳过创建一个新集合,仅使用业务对象已经拥有的一个即可.

What I would like to do is to have AutoMapper simply map the child objects from the DTO's collection to the existing collection on my BO. In other words, skip creating a new collection and simply use the one the business object already has.

有什么办法可以轻松地做到这一点?!?!?

Is there any way to easily accomplish this?!?!?

更新

也许更好的问题和更简单的解决方案是,是否可以定义实例化时AutoMapper将传递给集合的参数?我的子集合的定义如下:

Perhaps a better question, and simpler solution to my problem, is if it is possible to define arguments that AutoMapper will pass to the collection when instantiated? My child collection is defined like this:

public class ChildCollection : Collection<ChildObjects>
{
    public ChildCollection(ParentObject parent) { Parent = parent; }
}

如果我可以将AutoMapper配置为使用此构造函数并传递适当的对象,那将是完美的!

If I can configure AutoMapper to use this constructor and pass in the proper object, that would be PERFECT!

另一个更新

为清楚起见,这里是问题空间中的其他类:

For the sake of clarity, here are the other classes in the problem space:

public class ParentObject
{
    private ChildCollection _children;

    public ChildCollection Children
    {
        get
        {
            if (_children == null) _children = new ChildCollection(this);

            return _children;
        }
    }
}

public class ParentDTO
{
    public ICollection<ChildDTO> Children { get; set; }
}

public class ChildDTO
{
    public String SomeProperty { get; set; }
}

我以这种方式配置AutoMapper:

I configure AutoMapper this way:

Mapper.CreateMap<ParentDTO, ParentObject>();
Mapper.CreateMap<ChildDTO, ChildObject>();

这样做,我必须在父对象的Children属性中添加一个setter,并向ChildCollection添加一个默认(无参数)构造函数.尽管可以满足定义父子关系的需要,但似乎合理的做法是期望AutoMapper支持在创建子集合时将地图配置为使用特定的构造函数.像这样:

Doing so this way and I have to add a setter to the Children property in ParentObject and a default (parameterless) constructor to ChildCollection. While I can work around the need to define the parent-child relationship, it seems that it would be logical to expect AutoMapper to support configuring the map to use a specific constructor when creating the child collection. Something like this:

Mapper.CreateMap<ParentDTO, ParentObject>()
    .ForMember(obj => obj.Children, opt.MapFrom(dto => dto.Children))
    .ConstructUsing(col => new ChildCollection(obj));

请注意,我正在传递对"obj"的引用,该引用是要映射的ParentObject实例.

Notice that I am passing in the reference to "obj" which is the ParentObject instance being mapped.

推荐答案

事实证明,答案一直就在那里. UseDestinationValue选项正是我想要的.

It turns out that the answer was right there all along. The UseDestinationValue option does exactly what I want.

此选项指示AutoMapper使用目标对象上的现有属性,并将所有子属性或集合项映射到该对象中,而不是创建新的代理对象.

This options instructs AutoMapper to use the existing property on the target object and map any child properties or collection items into that object rather than creating a new proxy object.

所以,这是我在应用程序中要做的所有事情:

So, here's all I have to do in my application:

Mapper.CreateMap<ParentDTO, ParentObject>()
    .ForMember(obj => obj.Children,
           opt.UseDestinationValue());

瞧,瞧!现在,我可以实例化带有父级引用的子级集合,并在添加到集合中的每个项目中将引用设置回父级.

And, voila! Now I can instantiate the child collection, with parent reference, and setup the reference back to the parent in each item as it is added to the collection.

这篇关于映射子对象时,AutoMapper传递父引用的文章就介绍到这了,希望我们推荐的答案对大家有所帮助,也希望大家多多支持IT屋!

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