【发布时间】:2013-03-11 02:17:00
【问题描述】:
我有一个数据表 dt,它包含以下内容:
如您所见,这里有两组文件:基线(第 1-3 列)和目标(第 4-6 列)。所以在这种情况下,我有 4 个基线文件 m4、m5、m1 和 m3(第 5 行中的 m1 是从第 3 行复制的)和一个目标文件 m1。问题是基线文件 m1.txt 的信息是重复的,所以我尝试使用以下 LINQ 语句将其删除:
var extraneousRows = dt.Rows.Cast<DataRow>().
Where(
row => row["BASELINE_FOLDER"] == baselineSubfolder
&& row["BASELINE_FILE"] == baselineFilename
&& row["BASELINE_CHECKSUM"] == baselineChecksum
&& row["STATUS"] == "remove"
).ToArray();
foreach (DataRow dr in extraneousRows)
{
dt.Rows.Remove(dr);
}
这应该从 DataTable 中删除第三行,但它没有。如果我省略 && row["STATUS"] == "remove" 行,代码可以正常工作,所以我知道它是有效的。而且baselineSubfolder、baselineFilename 和baselineChecksum 的值是正确的,所以这不是问题所在。
但由于某种原因,当我包含关于状态列的那一行时,它不会检测到该行在 DataTable 中,即使它显然是根据 DataSet Visualizer(上图)。所以它永远不会进入 foreach 循环,也不会删除必要的文件。为什么???
我可能应该提到基线文件信息(前 4 行)是从数据库中检索的,而目标文件字段是根据用户输入生成的。不过,我看不出信息的来源有什么关系,因为我是直接查询 DataTable ...
更新
好的,在遵循 idipous 和 Jamie Keeling 的建议后,我确定问题与从未填充过的 foreach 循环有关。因为这个查询应该只返回一行,所以我完全消除了循环。我修改后的代码如下所示:
var extraneousRows = dt.Rows.Cast<DataRow>().
Where(
row => row["BASELINE_FOLDER"] == baselineSubfolder
&& row["BASELINE_FILE"] == baselineFilename
&& row["BASELINE_CHECKSUM"] == baselineChecksum
&& row["STATUS"] == "remove"
).SingleOrDefault();
dt.Rows.Remove(extraneousRows);
无论出于何种原因,extraneousRows 保持为空,并且最后一行正在生成运行时错误:IndexOutOfRangeException: The given DataRow is not in the current DataRowCollection
为什么这不起作用?
【问题讨论】:
-
图片中的状态是remove not remove。不知道是不是这个。
-
调试时可以断点查询并检查 lambda 的所有组件。
-
您是否检查过“extraneousRows”是否有要迭代的元素?
-
使用 SingleOrDefault() 代替 toArray();
-
不不,你根本不使用 foreach。你只有一个数据行 dt.Rows.Remove(extraneousRows);