簡體   English   中英

使用泛型的AutoMapper ResolveUsing會導致“提供的值是X類型但預期Y類型”錯誤

[英]AutoMapper ResolveUsing using generics cause “Value supplied is of type X but expected Y” error

我有一種情況,我必須使用AutoMapper將DTO映射到域對象。 這種映射需要一些復雜的管理,所以我創建了一個自定義值解析器。 我想從FooDTO獲得Foo 這兩個對象之間的唯一區別是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);

我收到此錯誤:

{“提供的值是AutoMapperDemo.FooDTO類型,但應為AutoMapperDemo.TrackedData'1 [AutoMapperDemo.ChildDTO]。更改值解析器源類型,或使用FromMember將提供的源值重定向到值解析器。\\ r \\ n提供的值是鍵入AutoMapperDemo.FooDTO,但期望的是AutoMapperDemo.TrackedData'1 [AutoMapperDemo.ChildDTO]。更改值解析器的源類型,或使用FromMember將提供的源值重定向到值解析器。“}

Github中提供了源代碼https : //github.com/josmonver/AutoMapperValueResolverIssue.git任何想法我為什么會收到此錯誤?

您可以在TrackedData<T>類中實現類似於UnionAll方法(更新+創建+刪除)的方法,然后映射它:

    Mapper.CreateMap<FooDTO, Foo>()
        .ForMember(d => d.Childs, opt => opt.MapFrom(src => src.UnionAll()));

暫無
暫無

聲明:本站的技術帖子網頁,遵循CC BY-SA 4.0協議,如果您需要轉載,請注明本站網址或者原文地址。任何問題請咨詢:yoyou2525@163.com.

 
粵ICP備18138465號  © 2020-2024 STACKOOM.COM