-->

我想知道有关的“产量”代码性能的连接和冲击的状态,而遍历数据读取器对象(I am wondering

2019-08-17 13:42发布

下面是我使用来从数据库中的数据我的示例代码:对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);
}

上面的代码工作当然好,但我想知道与上面的代码大约两个问题。

  1. 多久数据读取器的连接会被打开?
  2. 当我只考虑代码性能的因素,这是使用“收益率的回报”,而不是将记录到一个列表并返回整个列表是一个好主意?

Answer 1:

  1. 代码并不显示在您打开/关闭连接; 但是当你迭代的数据在这里, 读者会实际上只开放。 延期执行,等等,这是否是你的代码的唯一位.ToList()所以它会被罚款。 在更一般的情况,是:读者将开放供你采取迭代它的时间量; 如果你做一个.ToList()这将是最小的; 如果你做一个foreach和(为每个项目)让外部http请求,并等待20秒,然后是-这将是开放更长的时间。
  2. 两者都有自己的用途; 非缓冲的办法是伟大的,你要处理的数据流庞大的结果,而不必加载到一个在内存中的列表(或者甚至所有的人都在内存中一次); 返回一个列表保持迅速关闭了连接,并可以很容易地避免不小心使用连接,同时它已经有一个开放的阅读器,但并不适用于大型结果

如果返回一个迭代块,主叫方可以决定什么是明智的; 如果你总是返回一个列表,他们没有太多的选择。 第三种方式(我们在做短小精悍)是使他们的选择; 我们有一个可选的bool参数,默认为“返回一个列表”,但主叫方可以更改指示“返回一个迭代块”; 基本上:

bool buffered = true

在参数和:

var data = QueryInternal<T>(...blah...);
return buffered ? data.ToList() : data;

在执行。 在大多数情况下,返回一个列表是完全合理的,避免了很多问题,因此,我们提出的默认。



Answer 2:

多久数据读取器的连接会被打开?

直到连接将保持开放的reader被驳回,这意味着直到迭代结束这将是开放的。

当我只考虑代码性能的因素,这是用一个好主意, yield return ,而不是添加记录到一个列表并返回整个列表的?

这取决于以下几个因素:

  • 如果你不打算获取整个结果, yield return会帮您节省在数据网络上传输的量
  • 如果你不打算返回的数据转换为对象,或者如果多行被用来创建一个对象, yield return会帮你节省你的程序的高峰使用点使用的内存
  • 如果您打算迭代enture结果集在很短的时间段,会有使用没有性能损失yield return 。 如果迭代将要持续的时间对多个并发线程显著量,在RDBMS侧打开的游标的数量可能会变得超出。


Answer 3:

这个答案忽略所示实施缺陷和覆盖的总体思路。

这是一个权衡 - 这是不可能告诉它是否是不知道你的系统约束一个好主意 - 是这样的数据,你期望得到的数量,内存消耗,你愿意接受的数据库上,预期负载,等等



文章来源: I am wondering about the state of connection and impact on code performance by 'yield' while iterating over data reader object