我有一个类似于这个结构的代码: 我的表有108000行。 这个数据表实际上只是我读了一个标签分隔的文本文件来处理所以我把它放在数据表中。
private void Foo(DataTable myDataTable)
{
List<string> alreadyProcessed = new List<string>();
foreach(DataRow row in myDataTable.Rows)
{
string current = row["Emp"].ToString().Trim();
if (alreadyProcessed.Contains(current))
continue;
alreadyProcessed.Add(current);
var empRows = from p in myDataTable.AsEnumerable
where p["Emp"].ToString().Trim() == current
select new EmpClass
{
LastName = (string) p["lName"],
// some more stuff similr
};
// do some stuff with that EmpClass but they shouldn't take too long
}
}
运行这样的事情花了超过15分钟。我怎样才能改善这个?
答案 0 :(得分:1)
这是对您的代码进行相当天真的重写。
不要跟踪您已经处理过哪些员工,而是让员工对所有行进行分组,并分别对其进行处理。
var rowsPerEmployee =
(from DataRow row in dt.Rows
let emp = row["Emp"].ToString().Trim()
group row by emp into g
select g)
.ToDictionary(
g => g.Key,
g => g.ToArray());
foreach (var current in rowsPerEmployee.Keys)
{
var empRows = rowsPerEmployee[current];
... rest of your code here, note that empRows is not all the rows for a single employee
... and not just the lastname or similar
}
这将首先由员工对整个数据表进行分组,并从员工到该员工的行创建一个字典,然后在员工上循环并获取行。
答案 1 :(得分:0)
你应该按"EMP"
分组,否则你要经历每一行,而对于某些行,你要查询整个表格。像这样的东西
from p in myDataTable.AsEnumerable
group p by p.Field<string>("Emp") into g
select new { Emp = g.Key,
Data = g.Select(gg=>new EmpClass
{
LastName = gg.Field<string>("lName")
}
)
}
答案 2 :(得分:0)
在linq声明中,有一件事可能会减慢你的速度,那就是你要选择多少数据!您编写了“选择新的EmpClass&#39;”,并且根据您选择成为输出的列数(以及行/信息),可能会使事情大幅缩短。有关该问题的其他提示和技巧可在以下网址找到:http://visualstudiomagazine.com/articles/2010/06/24/five-tips-linq-to-sql.aspx