【问题标题】:AutoMapper error mapping from an IEnumerable<T> where T is an interface来自 IEnumerable<T> 的 AutoMapper 错误映射,其中 T 是接口
【发布时间】:2021-07-02 03:27:50
【问题描述】:

我有一种情况需要展平一组项目。

我这样设置我的映射配置文件:

CreateMap<IEnumerable<IMySetting>, IMySettingLookup>()
    .ForMember(l => l.MySetting1,
        o => o.MapFrom(sc =>
            sc.FirstOrDefault(s => s.SettingName == nameof(IMySettingLookup.MySetting1)).SettingValue))
    .ForMember(l => l.MySetting2,
        o => o.MapFrom(sc =>
            sc.FirstOrDefault(s => s.SettingName == nameof(IMySettingLookup.MySetting2)).SettingValue))
    .As<MySettingLookup>(); // notice this is a concrete type

当我这样调用地图函数时:

IEnumerable<IMySetting> settings =....;
IMySettingLookup lookup = _mapper.Map<IMySettingLookup>(settings);

我得到这个错误:

    AutoMapper.AutoMapperMappingException: Missing type map configuration or unsupported mapping.
    
    Mapping types:
    Object -> IMySettingLookup
    System.Object -> MyStuff.Models.IMySettingLookup
  Stack Trace: 
    lambda_method(Closure , Object , IMySettingLookup, ResolutionContext )

但是,当我使用具体类型设置映射配置文件并使用如下具体类型调用 Map 方法时,一切正常:

CreateMap<IEnumerable<MySetting>, MySettingLookup>() // notice everything is concrete types
   .ForMember(...).... 



and

IEnumerable<MySetting> settings =....;
IMySettingLookup lookup = _mapper.Map<MySettingLookup>(settings); // notice concrete types

我的问题是,当我的源类型是 IEnumerable&lt;T&gt; 其中 T 是一个接口时,如何定义我的映射配置文件?

编辑

我已将一个可重现的最小示例上传到https://github.com/nandun5/so-68219262-automapper

请注意,如果我只是使用具体类而不是接口,我不会看到任何问题。但是,在我的实际场景中,这对我来说并不是一个真正的选择,因为我所有的数据服务合同都是接口。

【问题讨论】:

    标签: c# .net .net-core automapper automapper-10


    【解决方案1】:

    .As&lt;MyType&gt; 似乎没有给出要使用的具体类型,而是告诉 AutoMapper 要查找哪个映射。 documentation 支持这一点:

    对于简单的情况,您可以使用 As 来将基础地图重定向到现有的派生地图

    在您的情况下,它正在查找 IEnumerable&lt;MySetting&gt;MySettingLookup 的映射,但没有找到。

    因此,您实际上要声明两个映射:

    CreateMap<IEnumerable<IMySetting>, MySettingLookup>()
       .ForMember(...);
    
    CreateMap<IEnumerable<IMySetting>, IMySettingLookup>()
       .As<MySettingLookup>();
    

    这将在尝试映射 &lt;IEnumerable&lt;MySetting&gt;, IMySettingLookup&gt; 时使用 &lt;IEnumerable&lt;MySetting&gt;, MySettingLookup&gt; 映射。

    或者,您可以简单地将.As&lt;MySettingLookup&gt;() 替换为以下.ConstructUsing(_ =&gt; new MySettingLookup())

    CreateMap<IEnumerable<IMySetting>, IMySettingLookup>()
       .ForMember(...)
       .ConstructUsing(_ => new MySettingLookup());
    

    【讨论】:

    • 感谢@Llama,不幸的是这对我不起作用。
    • @Nandun 我看过您的示例,我认为 Automapper 中可能存在错误:dotnetfiddle.net/mGbguS - 它似乎将源类型解释为“对象”。看起来这与 return new Setting[]return new ISetting[] 有关。我认为这可能与IEnumerable 的协变性质有关。
    • 我在 AutoMapper Git repo here 上添加了一个问题。
    • 等待他们修复它/解决问题,我建议从您的存储库方法中明确返回一个 ISetting 数组,或者明确说明您从/到的映射(即 @987654338 @)。
    猜你喜欢
    • 1970-01-01
    • 1970-01-01
    • 2016-07-06
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    相关资源
    最近更新 更多