c# - 使用 LINQ 和实体框架时如何避免重复 ToList?
问题描述
我有一个DbSet<T>
我需要投射到不同类型上的东西。对于投影,我使用Select
.
如果我直接打电话给Select
我的DbSet<T>
喜欢:
private IEnumerable<PersonPOCO> _getPersons(ILocator loc)
{
using(var service = loc.GetService())
{
return service.GetPersons().Select(p => Mapper.ToPoco(p));
}
}
这将抛出一个NotSupportedException
因为Select
实体框架无法识别(这很明显)。
所以我需要通过调用来“具体化”列表ToList()
:
private IEnumerable<PersonPOCO> _getPersons(ILocator loc)
{
using(var service = loc.GetService())
{
return service.GetPersons()
.ToList()
.Select(p => Mapper.ToPoco(p));
}
}
如果我这样离开它,Select
那么只有在真正枚举列表时才会评估“懒惰”。但是到那时,服务使用的 Context 将被释放(在using
语句之外),所以我将拥有一个DbContextDisposedException
.
所以我需要直接枚举里面的列表using
private IEnumerable<PersonPOCO> _getPersons(ILocator loc)
{
using(var prov = loc.GetService())
{
return prov.GetPersons()
.ToList()
.Select(p => Mapper.ToPOCO(p))
.ToList();
}
}
有没有办法避免ToList()
在同一条指令中调用两次?
解决方案
这里的问题是 EF 不知道如何处理DataViewMapper.ToPOCO
. 您可以使用AsEnumerable()
切换到 LINQ-to-Objects:
using (var prov = arg.GetProvider())
{
return prov.GetParamTypes()
.AsEnumerable()
.Select(p => DataViewMapper.ToPOCO(p))
.ToList();
}
这避免了中间列表/数组/等分配。
推荐阅读
- python - 奇怪的输出正则表达式 r'[-.\:alnum:](.*)'
- c++ - 使用构造函数从复杂类初始化变量的困惑
- c# - 防止 Automapper 返回空源的非空列表
- java - Apache Camel mockEndpoints() 模拟所有端点,而不是仅在建议路由中的端点
- angular - Angular 7:在 ngIf 上显示 Bootstrap 4 网格图像
- daml - 为 DAML 快速入门教程启动沙盒时出错
- javascript - HttpClient 和 Rxjs
- windows - Tensorflow CPU版本安装错误(DLL加载失败) Win7, Python 3.5.0
- c - C中的广度优先搜索代码,可能的堆栈溢出
- javascript - 试图理解绑定方法的底层代码