一个DTO你如何映射到使用AutoMapper嵌套对象现有的对象实例? [英] How do you map a Dto to an existing object instance with nested objects using AutoMapper?
问题描述
我有以下的DTO和实体嵌套子实体。
I have the following Dto and entity with a nested sub entity.
public class Dto
{
public string Property { get; set; }
public string SubProperty { get; set; }
}
public class Entity
{
public string Property { get; set; }
public SubEntity Sub { get; set; }
}
public class SubEntity
{
public string SubProperty { get; set; }
}
我
如何建立一个映射的 AutoMapper ,让我从数值更新的实体的现有实例的 DTO 的
How can I set up a mapping with AutoMapper that will allow me to update an existing instance of Entity with the values from a Dto.
我用 Mapper.Map(DTO,实体)
来更新现有的实体,但是当我试图映射 Dto.SubProperty
到 Entity.Sub.SubProperty
我得到一个例外的必须解析到顶级成员参数名称:lambdaEx pression 的。
I'm using Mapper.Map(dto, entity)
to update an existing entity but when I try to map Dto.SubProperty
to Entity.Sub.SubProperty
I get an exception for "must resolve to top-level member. Parameter name: lambdaExpression".
如果我创建 DTO
映射到子实体
使用 FromMember
然后 Entity.Sub
被替换子实体
,但是这不是我想要的。我只是想它来更新子实体
的现有实例对子属性
属性实体
。
If I create a mapping from Dto
to SubEntity
using FromMember
then Entity.Sub
gets replaced with a new instance of SubEntity
but that's not what I want. I just want it to update the properties of the existing instance of SubEntity
on the Sub
property of Entity
.
我怎样才能做到这一点?
推荐答案
我通过使用 ResolveUsing℃的组合,解决了这个问题; T>()
办法和实施<$和c $ C> IValueResolver 的 ConvertUsing&LT; T&GT;()
办法和实施 ITypeConverter&LT; TSource,TDestination&GT;
。
I solved it by using a combination of the ResolveUsing<T>()
method and implementing IValueResolver
and the ConvertUsing<T>()
method and implementing ITypeConverter<TSource,TDestination>
.
我的一些映射情况比一般包括双向映射和嵌套类和嵌套集合更加复杂。上面帮我解决这些问题。
Some of my mapping scenarios are more complicated than normal including bidirectional mapping and nested classes and nested collections. The above helped me to solve them.
根据要求,我已经包括了一个示例解决方案。本实施例是比实际类型我正在处理要简单得多。
As requested, I've included an example solution. This example is much simpler than the actual types I was dealing with.
using System;
using AutoMapper;
namespace TestAutoMapperComplex
{
public class Dto
{
public string Property { get; set; }
public string SubProperty { get; set; }
}
public class Entity
{
public string Property { get; set; }
public SubEntity Sub { get; set; }
}
public class SubEntity
{
public string SubProperty { get; set; }
}
static class MapperConfig
{
public static void Initialize()
{
Mapper.CreateMap<Dto, Entity>()
.ForMember(entity => entity.Sub, memberOptions => memberOptions.MapFrom(dto => dto));
Mapper.CreateMap<Dto, SubEntity>();
}
}
static class MapperConfig2
{
private class MyResolver : IValueResolver
{
public ResolutionResult Resolve(ResolutionResult source)
{
var destinationSubEntity = ((Entity)source.Context.DestinationValue).Sub;
Mapper.Map((Dto)source.Value, destinationSubEntity);
return source.New(destinationSubEntity, typeof(SubEntity));
}
}
public static void Initialize()
{
Mapper.CreateMap<Dto, Entity>()
.ForMember(entity => entity.Sub, memberOptions => memberOptions.ResolveUsing<MyResolver>());
Mapper.CreateMap<Dto, SubEntity>();
}
}
class Program
{
static void Main(string[] args)
{
MapperConfig.Initialize();
var dto = new Dto {Property = "Hello", SubProperty = "World"};
var subEntity = new SubEntity {SubProperty = "Universe"};
var entity = new Entity {Property = "Good bye", Sub = subEntity};
Mapper.Map(dto, entity);
Console.WriteLine(string.Format("entity.Property == {0}, entity.Sub.SubProperty == {1}", entity.Property, entity.Sub.SubProperty));
Console.WriteLine(string.Format("entity.Sub == subEntity: {0}", entity.Sub == subEntity));
}
}
}
如果您运行的例子,它是使用 MapperConfig
,你会得到以下输出:
If you run the example, which is using MapperConfig
, you'll get the following output:
entity.Property == Hello, entity.Sub.SubProperty == World
entity.Sub == subEntity: False
的字符串属性都得到更新,一会要他们,但 entity.Sub
被替换子实体$的新实例C $ C>这是没有好,当你想更新实体将被保存到数据库中的ORM的。
The string properties all get updated as one would want them to, but entity.Sub
gets replaced with a new instance of SubEntity
which is no good for when you are wanting to update entities for an ORM that will be persisted to a database.
如果您修改主
让 MapperConfig2
来代替,你仍然有更新的字符串属性之前,但是, entity.sub
仍具有子实体
,它有相同的实例之前。运行与 MapperConfig2
的例子给出了这样的输出:
If you modify Main
so that MapperConfig2
is used instead, you'll still have the string properties updated as before, but, entity.sub
still has the same instance of SubEntity
that it had before. Running the example with MapperConfig2
gives this output:
entity.Property == Hello, entity.Sub.SubProperty == World
entity.Sub == subEntity: True
在 MapperConfig2
的主要区别是, ResolveUsing
与 MyResolver 兼用code>来preserve的值
entity.Sub
。
The key difference in MapperConfig2
is that ResolveUsing
is used along with MyResolver
to preserve the value of entity.Sub
.
这篇关于一个DTO你如何映射到使用AutoMapper嵌套对象现有的对象实例?的文章就介绍到这了,希望我们推荐的答案对大家有所帮助,也希望大家多多支持IT屋!