1

给定以下代码片段:

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?

reader[0] 将始终是一个字符串 reader[0+?] 将是一个 double

如果可能的话,我想把所有的双打都拉到一个列表中。

4

4 回答 4

6

我想速度有点令人担忧。

然后,您将注意力完全集中在错误的问题上。

在您在这里所做的事情中,循环是效率最低的部分。更令人担忧的是,您正在从 adouble转换stringdouble. 至少将您的代码修复为:

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

您也可以创建具有已知大小的列表:

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

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

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

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

于 2013-07-11T03:28:38.147 回答
2

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

但无论如何,您可以执行以下操作:

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

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

于 2013-07-11T03:28:10.187 回答
0

我不认为你可以循环播放,因为

public class SqlDataReader : DbDataReader, IDataReader, IDisposable, IDataRecord

并且这个类没有实现IEnumerable

于 2013-07-11T03:22:53.610 回答
0

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

我相信这应该可行,但还没有建立数据集来测试它。

reader.Cast<Double>().Skip(1).ToList();
于 2013-07-11T03:33:24.073 回答