【问题标题】:Tell AutoMapper that a field is a top-level member告诉 AutoMapper 一个字段是顶级成员
【发布时间】:2018-08-06 05:00:40
【问题描述】:

我正在尝试使用 AutoMapper.QueryableExtensions 在 AutoMapper 中创建映射表达式来减轻一些痛苦

我有以下,这会带来关键的性能提升:

    private MapperConfiguration CreateConfiguration() {
        return new MapperConfiguration(cfg => cfg.CreateMap<Widget, WidgetNameDto>()
        .ForMember(dto => dto.Name,
            conf => conf.MapFrom(w => w.Name)));
    }

要了解性能提升,请参见此处:https://github.com/AutoMapper/AutoMapper/blob/master/docs/Queryable-Extensions.md 关键是查询受数据库级别的字段限制。

这很好用。但我预计需要做很多这样的投影。我试图从上面的 ForMember 子句中的语法中消除一些痛苦。

例如,我试过这个:

    public static IMappingExpression<TFrom, TTo> AddProjection<TFrom, TTo, TField>(this IMappingExpression<TFrom, TTo> expression,
        Func<TFrom, TField> from,
        Func<TTo, TField> to
        )
        => expression.ForMember(t => to(t), conf => conf.MapFrom(f => from(f)));

问题是我所做的一切都会出错:

AutoMapper.AutoMapperConfigurationException : Custom configuration for members is only supported for top-level individual members on a type.

即使传入的 Funcs 是顶级个人成员,这个事实也会在传递中丢失,所以我遇到了错误。我还尝试将 Func 更改为 Expression>。没用。

有什么方法可以简化 ForMember 子句的语法?理想情况下,我只会传入两个相关字段。

【问题讨论】:

    标签: automapper entity-framework-core iqueryable


    【解决方案1】:

    首先,不需要为按名称匹配的字段/属性添加映射 - AutoMapper 按约定自动映射它们(这就是它被称为基于约定的对象-对象映射器的原因)。如果只在投影中包含一些属性,您可以使用Explicit expansion 功能。

    其次,您在ForMember 语法中所称的痛苦实际上是一种灵活性。比如显式展开等行为可以通过conf参数来控制,所以不仅仅是指定源。

    话虽如此,您所问的都是可能的。您必须将from/to 类型更改为Expression

     Expression<Func<TFrom, TField>> from,
     Expression<Func<TTo, TField>> to
    

    实现简单如下:

    => expression.ForMember(to, conf => conf.MapFrom(from));
    

    【讨论】:

      猜你喜欢
      • 1970-01-01
      • 2012-07-22
      • 2020-04-10
      • 1970-01-01
      • 2022-08-16
      • 2023-03-20
      • 1970-01-01
      • 2014-12-21
      相关资源
      最近更新 更多