给出以下代码片段:
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]将永远是一个字符串 读者[0+?]将是双重
如果可能,我想将所有双打拉入列表。
答案 0 :(得分:6)
我认为速度有点令人担忧。
然后你专注于完全错误的问题。
在你正在做的事情中,循环是最少低效的部分。更令人担心的是,您要从double
转换为string
,然后再转回double
。至少修改你的代码:
for (var i = 1; i < count; i++)
{
data.Add(reader.GetDouble(i));
}
您也可以使用已知尺寸创建列表:
List<double> data = new List<double>(count - 1);
即便如此,我强烈怀疑与序列化和数据库访问相比,这将无关紧要。
无论你做什么,某些东西都会循环播放。您可以不遗余力地隐藏循环(例如,通过编写扩展方法迭代一行中的所有值) - 但实际上,我没有看到它在这里有任何问题
我强烈建议您避免微观优化,直到您证明出现问题为止。如果你担心的这些代码根本就是一个瓶颈,我会感到非常惊讶。通常,您应该编写最简单的代码来实现您的目标,决定您的性能标准,然后对其进行测试。只在需要时才从简单的代码中移开。
答案 1 :(得分:2)
我可以看到删除forloop
的唯一方法是使用Enumerable.Range
。
但无论如何你可以做点什么:
var data = new List<double>(Enumerable.Range(1, count).Select(i => reader.GetDouble(i)));
但我觉得这个approch没什么好处,只是让代码不可读
答案 2 :(得分:0)
我不认为你可以循环使用它,因为
public class SqlDataReader : DbDataReader, IDataReader, IDisposable, IDataRecord
并且此类未实现IEnumerable
答案 3 :(得分:0)
您可以使用LINQ Cast方法获取可以使用其他LINQ方法的内容,但我同意其他海报 - for循环没有任何问题。 LINQ方法只会在后台使用效率较低的循环。
我相信这应该可行,但还没有设置数据集来测试它。
reader.Cast<Double>().Skip(1).ToList();