如何使用AutoMapper将具有多个通用列表的对象映射到具有相应非泛型列表的另一个对象?

时间:2016-10-12 19:57:04

标签: f# automapper

我创建了一个ListTypeConverter:

type ListTypeConverter<'source, 'destination>() =
    interface ITypeConverter<'source list, Proxies.List> with
        member this.Convert(source, destination, context) =
            let proxyList = new Proxies.List()
            source 
            |> List.map(fun item -> _mapper.Map<'source, 'destination>(item))
            |> List.iter(fun item -> proxyList.addEnd(item) |> ignore)
            proxyList

用法:ForMemberFs by Ian Griffiths

this.CreateMap<SourceItemType list, Proxies.List>().ConvertUsing<ListTypeConverter<SourceItemType, DestItemType>>()

this.CreateMap<SourceType, DestType>().
    ForMemberFs((fun d -> d.MyNonGenericList), (fun opts -> opts.MapFrom(fun s -> s.MyGenericList))).

如果我的主地图上只有一个属性从'a list -> Proxy.List映射,则此方法可以正常工作。但是当我从'b -> Proxy.List引入第二个映射时,我得到一个InvalidCastException。

引入第二个映射会导致异常:

this.CreateMap<SourceItemType list, Proxies.List>().ConvertUsing<ListTypeConverter<SourceItemType, DestItemType>>()
this.CreateMap<SourceItemType2 list, Proxies.List>().ConvertUsing<ListTypeConverter<SourceItemType2, DestItemType2>>()

this.CreateMap<SourceType, DestType>().
    ForMemberFs((fun d -> d.MyNonGenericList), (fun opts -> opts.MapFrom(fun s -> s.MyGenericList))).
    ForMemberFs((fun d -> d.MyNonGenericList2), (fun opts -> opts.MapFrom(fun s -> s.MyGenericList2))).

例外:

Unable to cast object of type 'obj' to type 'DestItemType'

1 个答案:

答案 0 :(得分:1)

所以,我的问题比F#和AutoMapper要深一些。 Proxies.List类型实际上是通过我们在内部编写的Microsoft Dynamics AX的TypeProvider获得的。我想从等式中排除该变量,因此我使用System.Collections.Generic.List<'t> -> System.Collections.ArrayList(非通用)编写了一个简单的脚本,并且我能够成功地从ArrayList中的项目转换回正确的& #34;目的地&#34;类型。

虽然我在这里,但我们为AutoMapper提出了一些非常酷的F#助手:

type OptionExpressions =
    static member MapFrom<'source, 'destination, 'sourceMember, 'destinationMember> (e: 'source -> 'sourceMember) =
        System.Action<IMemberConfigurationExpression<'source, 'destination, 'destinationMember>> (fun (opts: IMemberConfigurationExpression<'source, 'destination, 'destinationMember>) -> opts.MapFrom(e))
    static member UseValue<'source, 'destination, 'value> (e: 'value) =
        System.Action<IMemberConfigurationExpression<'source, 'destination, 'value>> (fun (opts: IMemberConfigurationExpression<'source, 'destination, 'value>) -> opts.UseValue(e))
    static member Ignore<'source, 'destination, 'destinationMember> () =
        System.Action<IMemberConfigurationExpression<'source, 'destination, 'destinationMember>> (fun (opts: IMemberConfigurationExpression<'source, 'destination, 'destinationMember>) -> opts.Ignore())

用法:

// Shortened local helpers
let mapFrom = OptionExpressions.MapFrom
let ignoreMap = OptionExpressions.Ignore
let useValue = OptionExpressions.UseValue

this.CreateMap<Source, Destination>()
    .ForMemberFs((fun d -> d.DestMember1),  mapFrom (fun s -> s.SourceMember1))
    .ForMemberFs((fun d -> d.DestMember2),  useValue (MyValue))
    .ForMemberFs((fun d -> d.DestMember3),  ignoreMap ())