我想知道迭代数据读取器对象时的连接状态以及“yield”对代码性能的影响

2024-01-11

这是我用来从数据库获取数据的示例代码: 在 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. 当我仅考虑代码性能因素时,使用“yield return”而不是将记录添加到列表中并返回整个列表是一个好主意吗?

  1. 您的代码不显示您打开/关闭连接的位置;但是reader这里实际上只会开放当你迭代数据时。延迟执行等。执行此操作的代码中唯一的部分是.ToList(),所以会没事的。在更一般的情况下,是的:读者将开放您迭代它所花费的时间;如果你做一个.ToList()这将是最小的;如果你做一个foreach并且(对于每个项目)发出外部 http 请求并等待 20 秒,然后是的 - 它将打开更长时间。
  2. 两者都有各自的用途;非缓冲方法非常适合您想要作为流处理的巨大结果,而无需将它们加载到单个内存列表中(甚至一次将它们全部放入内存中);返回列表可以使连接快速关闭,并且可以轻松避免在已经有打开的读取器时意外使用该连接,但对于大型结果而言并不理想

如果返回一个迭代器块,调用者可以决定什么是正常的;如果你总是返回一个列表,他们就没有太多选择。第三种方法(我们在衣冠楚楚的情况下这样做)是让他们做出选择;我们有一个可选的bool参数默认为“返回列表”,但调用者可以更改该参数以指示“返回迭代器块”;基本上:

bool buffered = true

在参数中,并且:

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

在实施中。在大多数情况下,返回列表是完全合理的,并且可以避免很多问题,因此我们将其设为默认值。

本文内容由网友自发贡献,版权归原作者所有,本站不承担相应法律责任。如您发现有涉嫌抄袭侵权的内容,请联系:hwhale#tublm.com(使用前将#替换为@)

我想知道迭代数据读取器对象时的连接状态以及“yield”对代码性能的影响 的相关文章

随机推荐