我有一个场景,我必须使用AutoMapper将DTO映射到域对象。这种映射需要一些复杂的管理,所以我创建了一个自定义值解析器。我想从Foo
获取FooDTO
。这两个对象之间的唯一区别是Foo
具有ICollection<Child>
而FooDTO
具有TrackedData<ChildDTO>
,其中TrackeData<T>
是具有3 ICollection<T>
的对象}。
这是我的简化方案:
public class TrackedData<T>
{
public ICollection<T> Updated { get; set; }
public ICollection<T> Created { get; set; }
public ICollection<T> Deleted { get; set; }
public TrackedData()
{
Updated = new List<T>();
Created = new List<T>();
Deleted = new List<T>();
}
}
public class Foo
{
private List<Child> _childs;
public string Name { get; set; }
public ICollection<Child> Childs
{
get
{
if (_childs == null)
_childs = new List<Child>();
return _childs;
}
set
{
_childs = (List<Child>)value;
}
}
}
public class Child
{
public string Description { get; set; }
}
public class FooDTO
{
public string Name { get; set; }
public TrackedData<ChildDTO> Childs { get; set; }
}
public class ChildDTO
{
public string Description { get; set; }
}
public class Program
{
public static void Main(string[] args)
{
Mapper.CreateMap(typeof(TrackedData<>), typeof(TrackedData<>));
Mapper.CreateMap<ChildDTO, Child>();
Mapper.CreateMap<FooDTO, Foo>()
.ForMember(d => d.Childs, opt => opt.ResolveUsing<TrackedDataResolver<ChildDTO, Child>>());
FooDTO fooDTO = CreateFakeFooDTO();
Foo foo = Mapper.Map<FooDTO, Foo>(fooDTO);
}
private static FooDTO CreateFakeFooDTO() { /* omitted for simplicity */ }
private static TrackedData<ChildDTO> CreateFakeTrackedDataChildDTO() { /* omitted for simplicity */ }
private static ICollection<ChildDTO> CreateFakeListChildDTO() { /* omitted for simplicity */ }
private static ChildDTO CrateFakeChildDTO(){ /* omitted for simplicity */ }
}
public class TrackedDataResolver<TSource, TDestination> : ValueResolver<TrackedData<TSource>, ICollection<TDestination>>
{
protected override ICollection<TDestination> ResolveCore(TrackedData<TSource> source)
{
TrackedData<TDestination> trackedDestination = new TrackedData<TDestination>();
ICollection<TDestination> destination = new List<TDestination>();
trackedDestination = Mapper.Map<TrackedData<TSource>, TrackedData<TDestination>>(source);
foreach (var o in trackedDestination.Created)
{
// Do stuff...
destination.Add(o);
}
foreach (var o in trackedDestination.Updated)
{
// Do stuff...
destination.Add(o);
}
foreach (var o in trackedDestination.Deleted)
{
// Do stuff...
destination.Add(o);
}
return destination;
}
}
执行此行时
Foo foo = Mapper.Map<FooDTO, Foo>(fooDTO);
我收到此错误:
{&#34;提供的值是AutoMapperDemo.FooDTO类型,但预计AutoMapperDemo.TrackedData&#39; 1 [AutoMapperDemo.ChildDTO]。更改值解析程序源类型,或使用FromMember重定向提供给值解析程序的源值。\ r \ n提供的值是AutoMapperDemo.FooDTO类型但预期AutoMapperDemo.TrackedData&#39; 1 [AutoMapperDemo.ChildDTO]。更改值解析程序源类型,或使用FromMember重定向提供给值解析器的源值。&#34;}
Source code在Github中可用:https://github.com/josmonver/AutoMapperValueResolverIssue.git 知道为什么我会收到这个错误吗?
答案 0 :(得分:1)
您可以在UnionAll
类中实现TrackedData<T>
方法(已更新+已创建+已删除)并将其映射到
Mapper.CreateMap<FooDTO, Foo>()
.ForMember(d => d.Childs, opt => opt.MapFrom(src => src.UnionAll()));