entity-framework-core - 如何将 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 版。我怎么做?
解决方案
从 8.0 开始,您可以使用 IMapper.ProjectTo
这意味着现在IMapper
接口有一个方法ProjectTo
(类似于Map
)。因此,虽然您仍然需要注入IMapper
(但如果您使用 ,则无论如何都需要它Map
,所以没有区别),您不需要QueryableExtensions
和ProjectTo
扩展方法 - 您只需使用接口方法(类似于Map
):
return await _mapper.ProjectTo<SomeViewModel>(dbContext.SomeEntity)
.ToListAsync();
_mapper.ProjectTo
请注意,和之间存在根本区别Select(_mapper.Map)
——前者被翻译成 SQL 并在服务器端执行,而后者导致客户端评估并需要Include
/ ThenInclude
(或延迟加载)才能正常运行。
推荐阅读
- parsing - 如何跨 *nix TTY/终端仿真器解释/解析键盘和鼠标输入?
- r - 在R中的列表中查找行中最频繁的元素
- javascript - 离子虚拟滚动渲染延迟
- javascript - 从打印 java-script window.print 中删除应用程序名称和网页地址
- python - 用python从json内容中提取一些数据
- javascript - 如何使用快速服务器为 Web 组件应用程序提供服务
- html - 在选择选项前添加 svg 图像
- autodesk-forge - Forge DA for Revit 多个版本
- ios - 如何分享 iOS 应用的交互式演示
- android - 向 RenderScript.create() 提供“上下文”时遇到问题