【发布时间】:2015-01-20 16:48:55
【问题描述】:
我被这个问题困住了。 我可以通过使用 foreach 来解决这个问题,但必须有更好的解决方案。
我有两个数据表。 首先有一个名为“Por”的列 第二个有两列名为“FirstPor”和“LastPor”。 我的目标是使用 LINQ 根据这样的条件创建新的数据表。
foreach ( DataRow row in FirstDatatable.Rows )
{
foreach ( DataRow secondRow in SecondDatatable.Rows )
{
if ( row["Por"] >= secondRow["FirstPor"] && row["Por"] <= secondRow["LastPor"] )
FinalDataTable.Rows.Add(row);
}
}
我是 LINQ 的新手,这对我来说可能是个问题。我可以通过 Parallel.Foreach 做到这一点,但我认为 LINQ 可以更快。条件很简单。从第一个表(“Por”列)中获取每个数字,并检查它属于第二个表的哪一行(“Por”>=“FirstPor”&&“Por”
是的,我刚刚将并行代码修改为混合 LINQ/Parallel,看来我已经完成了。我使用了 James 和 Rahul 编写的内容并将其放入我的代码中。现在,这个过程需要 52 秒来估计 421 000 行:) 好多了。
public class Range
{
public int FirstPor { get; set; }
public int LastPor { get; set; }
public int PackageId { get; set; }
}
var ranges = (from r in tmpDataTable.AsEnumerable()
select new Range
{
FirstPor = Int32.Parse(r["FirstPor"] as string),
LastPor = Int32.Parse(r["LastPor"] as string),
PackageId = Int32.Parse(r["PackageId"] as string)
}).ToList();
Parallel.ForEach<DataRow>(dt.AsEnumerable(), row =>
{
int por = Int32.Parse(row["Por"].ToString());
lock (locker)
{
row["PackageId"] = ranges.First(range => por >= range.FirstPor && por <= range.LastPor).PackageId;
}
worker.ReportProgress(por);
});
【问题讨论】:
-
它的速度与它需要的一样快。除非你在谈论成千上万的行。在这种情况下,Linq 不会帮助您,但明智的多线程策略可能会。
-
是的,我在邮局工作,所以有一个大数据。我的第一个数据表有大约 700 000 行,第二个表有大约 20 000 行,所以通常当我使用 Parallel.Foreach 时,我需要大约 7 分钟才能得到我的最终表。但我认为 LINQ 应该像 SQL 一样快。
-
如果您正在谈论修改原始查询以防止这种内存连接,那么可能。您需要显示您的两个查询(或等效的、已清理的版本)并询问如何执行您的联接。
-
@Leeon82 Linq 只是
foreach使用的相同机制的包装器,它使查询更容易编写,但不一定性能更好。我想知道您的逻辑是否最佳,因为您正在扫描第二个表中的每条记录以查找第一个表中的每条记录。 -
我能够在查询开始前将所有字符串列转换为 int。
标签: c# linq join foreach datatable