如何在Automapper 8.0依赖项注入中使用ProjectTo

Ale*_*lex 4 automapper entity-framework-core

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

这是我设法开始工作的示例:

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

        return await _dbContext.SomeEntity
            .ProjectTo<SomeViewModel>(_mapper.ConfigurationProvider)
            .ToListAsync();
    }
Run Code Online (Sandbox Code Playgroud)

上面的调用返回了所有期望的记录,但是它既需要在存储库的构造函数中注入IMapper,也需要对AutoMapper.QueryableExtensions的Using引用。

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

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

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

这些文档http://docs.automapper.org/en/stable/Dependency-injection.html声明如下:

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

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

    public IEnumerable<SomeViewModel> GetStuff() {

        return _dbContext.SomeEntity
            .Select(_mapper.Map<SomeViewModel>)
            .ToList();
    }
Run Code Online (Sandbox Code Playgroud)

但是,该方法返回0条记录(前一个返回所有记录),并且扩展的Select不支持将方法从Async转换为sync,因为ToListAsync()。显然我缺少了一些东西。另外,我不确定这是否是正确的技术,因为第二组文档讨论了针对版本8.0使用IMapper.ProjectTo而不将配置传递给扩展方法。我怎么做?

Iva*_*oev 13

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

这意味着现在IMapperinterface具有一个方法ProjectTo(类似于Map)。因此,尽管您仍然需要注入IMapper(但是如果您使用Map,则仍然需要注入,因此没有区别),则不需要QueryableExtensionsProjectTo 扩展方法-您只需使用接口方法(类似于Map):

return await _mapper.ProjectTo<SomeViewModel>(dbContext.SomeEntity)
    .ToListAsync();
Run Code Online (Sandbox Code Playgroud)

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