这是我用来从数据库获取数据的示例代码:
在 DAO 层:
public IEnumerable<IDataRecord> GetDATA(ICommonSearchCriteriaDto commonSearchCriteriaDto)
{
using(DbContext)
{
DbDataReader reader = DbContext.GetReader("ABC_PACKAGE.GET_DATA", oracleParams.ToArray(), CommandType.StoredProcedure);
while (reader.Read())
{
yield return reader;
}
}
}
在 BO 层上,我调用上述方法,如下所示:
List<IGridDataDto> GridDataDtos = MapMultiple(_costDriversGraphDao.GetGraphData(commonSearchCriteriaDto)).ToList();
在映射器层 MapMultiple 方法定义如下:
public IGridDataDto MapSingle(IDataRecord dataRecord)
{
return new GridDataDto
{
Code = Convert.ToString(dataRecord["Code"]),
Name = Convert.ToString(dataRecord["Name"]),
Type = Convert.ToString(dataRecord["Type"])
};
}
public IEnumerable<IGridDataDto> MapMultiple(IEnumerable<IDataRecord> dataRecords)
{
return dataRecords.Select(MapSingle);
}
上面的代码运行良好,但我想知道上面的代码有两个问题。
- 数据读取器的连接将打开多长时间?
- 当我仅考虑代码性能因素时,使用“yield return”而不是将记录添加到列表中并返回整个列表是一个好主意吗?
- 您的代码不显示您打开/关闭连接的位置;但是reader这里实际上只会开放当你迭代数据时。延迟执行等。执行此操作的代码中唯一的部分是
.ToList()
,所以会没事的。在更一般的情况下,是的:读者将开放您迭代它所花费的时间;如果你做一个.ToList()
这将是最小的;如果你做一个foreach
并且(对于每个项目)发出外部 http 请求并等待 20 秒,然后是的 - 它将打开更长时间。
- 两者都有各自的用途;非缓冲方法非常适合您想要作为流处理的巨大结果,而无需将它们加载到单个内存列表中(甚至一次将它们全部放入内存中);返回列表可以使连接快速关闭,并且可以轻松避免在已经有打开的读取器时意外使用该连接,但对于大型结果而言并不理想
如果返回一个迭代器块,调用者可以决定什么是正常的;如果你总是返回一个列表,他们就没有太多选择。第三种方法(我们在衣冠楚楚的情况下这样做)是让他们做出选择;我们有一个可选的bool
参数默认为“返回列表”,但调用者可以更改该参数以指示“返回迭代器块”;基本上:
bool buffered = true
在参数中,并且:
var data = QueryInternal<T>(...blah...);
return buffered ? data.ToList() : data;
在实施中。在大多数情况下,返回列表是完全合理的,并且可以避免很多问题,因此我们将其设为默认值。
本文内容由网友自发贡献,版权归原作者所有,本站不承担相应法律责任。如您发现有涉嫌抄袭侵权的内容,请联系:hwhale#tublm.com(使用前将#替换为@)