Gid*_*sey 12 .net c# nested dto automapper
我有以下Dto和实体与嵌套的子实体.
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; }
}
Run Code Online (Sandbox Code Playgroud)
如何使用AutoMapper设置映射,这将允许我使用Dto中的值更新现有的Entity实例.
我正在使用Mapper.Map(dto, entity)
更新现有实体但是当我尝试映射Dto.SubProperty
到时,Entity.Sub.SubProperty
我得到一个例外,"必须解析为顶级成员.参数名称:lambdaExpression".
如果我从创建一个映射Dto
到SubEntity
使用FromMember
,然后Entity.Sub
被用的新实例所取代SubEntity
,但是这不是我想要的.我只是想让它更新属性的现有实例SubEntity
的Sub
属性Entity
.
我怎样才能做到这一点?
Gid*_*sey 20
我通过结合使用ResolveUsing<T>()
方法和实现IValueResolver
以及ConvertUsing<T>()
方法和实现来解决它ITypeConverter<TSource,TDestination>
.
我的一些映射场景比正常情况更复杂,包括双向映射和嵌套类以及嵌套集合.以上帮助我解决了这些问题.
根据要求,我已经包含了一个示例解决方案.这个例子比我正在处理的实际类型简单得多.
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));
}
}
}
Run Code Online (Sandbox Code Playgroud)
如果您运行正在使用的示例,MapperConfig
您将获得以下输出:
entity.Property == Hello, entity.Sub.SubProperty == World
entity.Sub == subEntity: False
Run Code Online (Sandbox Code Playgroud)
字符串属性都会按照人们希望的那样进行更新,但是当您想要更新将持久保存到数据库的ORM的实体时entity.Sub
,SubEntity
它会替换为新的实例.
如果修改Main
,这样MapperConfig2
来代替,你仍然有串属性之前更新,但是,entity.sub
仍然有同样的实例SubEntity
,它收到了.运行示例MapperConfig2
提供此输出:
entity.Property == Hello, entity.Sub.SubProperty == World
entity.Sub == subEntity: True
Run Code Online (Sandbox Code Playgroud)
在关键的区别MapperConfig2
是ResolveUsing
用来一起MyResolver
保存的价值entity.Sub
.