Enumerate SqlDataReader Columns

本文关键字:Columns SqlDataReader Enumerate | 更新日期: 2023-09-27 18:21:50

给定以下代码片段:

using (var reader = cmd.ExecuteReader())
{
    while(reader.Read())
    {
        var count = reader.FieldCount; // the first column must be name all subsequent columns are treated as data
        var data = new List<double>();
        for (var i = 1; i < count; i++)
        {
            data.Add(Convert.ToDouble(reader[i].ToString()));
        }
        barChartSeries.Add(new ColumnBarChart.ColumnChartSeries((string)reader[0],
                                                                data));
        columnChart.xAxis.categories.Add((string)reader[0]);
    }
}

有没有一种简单的方法可以消除for循环?也许用linq?

读取器[0]将始终是一个字符串阅读器[0+?]将是双

如果可能的话,我想把所有的双打都列入一个名单。

Enumerate SqlDataReader Columns

我想速度有点令人担忧。

然后你就把注意力集中在完全错误的问题上了。

在您正在做的事情中,循环是效率最低的部分。更令人担忧的是,您正在从double转换为string,然后再转换回double。至少将您的代码修复为:

for (var i = 1; i < count; i++)
{
    data.Add(reader.GetDouble(i));
}

你也可以创建已知大小的列表:

List<double> data = new List<double>(count - 1);

即便如此,我还是强烈怀疑,和序列化和数据库访问相比,这将是无关紧要的。

无论你做什么,某些东西都将循环。您可以不遗余力地隐藏循环(例如,通过编写一个扩展方法来迭代一行中的所有值),但实际上,我认为这里没有任何问题。

我强烈建议您在证明存在问题之前避免进行微观优化。如果你担心的这段代码是一个瓶颈,我会非常惊讶。一般来说,你应该编写最简单的代码来实现你想要的,决定你的性能标准,然后根据它们进行测试。只有在需要时才远离简单的代码。

我能看到的删除forloop的唯一方法是使用Enumerable.Range

但无论如何,你可以做一些类似的事情:

   var data = new List<double>(Enumerable.Range(1, count).Select(i => reader.GetDouble(i)));

但我认为这种方法没有任何好处,它只会使代码无法读取

我认为你不能循环使用它,因为

public class SqlDataReader : DbDataReader, IDataReader, IDisposable, IDataRecord

并且该类不实现IEnumerable

您可以使用LINQ Cast方法来获得可以使用其他LINQ方法的东西,但我同意其他海报的观点-for循环没有错。LINQ方法只会在后台使用效率较低的循环。

我相信这应该有效,但还没有建立一个数据集来测试它

reader.Cast<Double>().Skip(1).ToList();