C# 我想知道';收益率';在数据读取器对象上迭代时
以下是我用于从数据库获取数据的示例代码: 在DAO层上:C# 我想知道';收益率';在数据读取器对象上迭代时,c#,linq,using,datareader,yield-return,C#,Linq,Using,Datareader,Yield Return,以下是我用于从数据库获取数据的示例代码: 在DAO层上: public IEnumerable<IDataRecord> GetDATA(ICommonSearchCriteriaDto commonSearchCriteriaDto) { using(DbContext) { DbDataReader reader = DbContext.GetReader("ABC_PACKAGE.GET_DATA", oracleParams.ToArray()
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;
}
}
}
public IEnumerable GetDATA(ICommonSearchCriteriaDto commonSearchCriteriaDto)
{
使用(DbContext)
{
DbDataReader=DbContext.GetReader(“ABC_PACKAGE.GET_DATA”,oracleParams.ToArray(),CommandType.storedProcess);
while(reader.Read())
{
回传阅读器;
}
}
}
在BO层上,我调用上述方法,如下所示:
List<IGridDataDto> GridDataDtos = MapMultiple(_costDriversGraphDao.GetGraphData(commonSearchCriteriaDto)).ToList();
List GridDataDtos=MapMultiple(_costDriversGraphDao.GetGraphData(commonSearchCriteriaDto)).ToList();
在mapper图层上,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);
}
public-igridatadto-MapSingle(IDataRecord数据记录)
{
返回新的GridDataDto
{
Code=Convert.ToString(dataRecord[“Code”]),
Name=Convert.ToString(数据记录[“Name”]),
Type=Convert.ToString(数据记录[“类型”])
};
}
公共IEnumerable MapMultiple(IEnumerable数据记录)
{
返回数据记录。选择(MapSingle);
}
上面的代码运行良好,但我想知道上面的代码有两个问题
.ToList()
,因此它不会有问题。在更一般的情况下,是的:读者将在您迭代它所花费的时间内打开它;如果您执行.ToList()
操作,则这将是最小的;如果您对每个项目执行一个foreach
,并发出一个外部http请求并等待20秒,则是-它将打开更长时间bool
参数,默认为“返回列表”,但调用者可以更改该参数以指示“返回迭代器块”;基本上:
bool buffered = true
在参数中,以及:
var data = QueryInternal<T>(...blah...);
return buffered ? data.ToList() : data;
var数据=查询内部(…废话…);
返回缓冲?data.ToList():数据;
在执行中。在大多数情况下,返回列表是完全合理的,可以避免很多问题,因此我们将其作为默认值
数据读取器的连接将打开多长时间
连接将保持打开状态,直到读取器
被解除,这意味着它将一直打开,直到迭代结束
<>当我只考虑代码性能因子时,使用<代码>收益返回<代码>是不是一个好主意,而不是在列表中添加记录并返回整个列表?
这取决于几个因素:
- 如果您不打算获取整个结果,
将帮助您节省在网络上传输的数据量yield return
- 如果您不打算将返回的数据转换为对象,或者如果使用多行创建单个对象,
将帮助您节省程序峰值使用点使用的内存yield return
- 如果您计划在短时间内迭代enture结果集,则使用
不会导致性能损失。如果迭代将在多个并发线程上持续相当长的时间,那么RDBMS端打开的游标数量可能会超过yield return