首页 > 解决方案 > 如何将 ProjectTo 与 Automapper 8.0 依赖注入一起使用

问题描述

我在我的项目中使用 Automapper 的 (8.0) DI 模式,并希望在我的 Entity Framework Core 实体查询中开始使用 ProjectTo。

这是我设法开始工作的一个例子:

public async Task<IEnumerable<SomeViewModel>> GetStuffAsync() {

    return await _dbContext.SomeEntity
        .ProjectTo<SomeViewModel>(_mapper.ConfigurationProvider)
        .ToListAsync();
}
    

上面的调用返回所有预期的记录,但它需要注入IMapper在存​​储库的构造函数中注入以及对 AutoMapper.QueryableExtensions 的使用引用。

我找到了两个版本的 AutoMapper 文档,它们似乎提供了相互冲突的信息。

这些文档https://automapperdocs.readthedocs.io/en/latest/Dependency-injection.html声明如下:

IQueryable.ProjectTo使用 DI 与使用扩展方法实际上是互斥的 。改为使用 IEnumerable.Select(_mapper.Map<DestinationType>).ToList()

这些文档http://docs.automapper.org/en/stable/Dependency-injection.html说明了这一点:

从 8.0 开始,您可以使用IMapper.ProjectTo. 对于旧版本,您需要将配置传递给扩展方法 IQueryable.ProjectTo<T>(IConfigurationProvider)

按照第一个文档的示例,我将查询转换为:

public IEnumerable<SomeViewModel> GetStuff() {

    return _dbContext.SomeEntity
        .Select(_mapper.Map<SomeViewModel>)
        .ToList();
}

但是,该方法返回 0 条记录(前一个返回所有内容),并且需要从异步转换为同步的方法,因为扩展 Select 不支持 ToListAsync()。显然我错过了一些东西。另外,我不确定这是否是正确的技术,因为第二组文档谈到在不将配置传递给扩展方法的情况下将 IMapper.ProjectTo 用于 8.0 版。我怎么做?

标签: entity-framework-coreautomapper

解决方案


从 8.0 开始,您可以使用 IMapper.ProjectTo

这意味着现在IMapper接口有一个方法ProjectTo(类似于Map)。因此,虽然您仍然需要注入IMapper(但如果您使用 ,则无论如何都需要它Map,所以没有区别),您不需要QueryableExtensionsProjectTo 扩展方法 - 您只需使用接口方法(类似于Map):

return await _mapper.ProjectTo<SomeViewModel>(dbContext.SomeEntity)
    .ToListAsync();

_mapper.ProjectTo请注意,和之间存在根本区别Select(_mapper.Map)——前者被翻译成 SQL 并在服务器端执行,而后者导致客户端评估并需要Include/ ThenInclude(或延迟加载)才能正常运行。


推荐阅读