以下を含む DataTable dt があります。
ご覧のとおり、ここには 2 つのファイル セットがあります。ベースライン (列 1 ~ 3) とターゲット (列 4 ~ 6) です。この場合、4 つのベースライン ファイル m4、m5、m1、および m3 (行 5 の m1 は行 3 からコピーされます) と 1 つのターゲット ファイル 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 から 3 行目が削除されますが、そうではありません。行を省略してもコードは && row["STATUS"] == "remove"
正常に機能するので、機能していることがわかります。また、baselineSubfolder、baselineFilename、baselineChecksum の値は正しいため、問題はありません。
しかし、何らかの理由で、ステータス列に関する行を含めると、DataSet ビジュアライザー (上の写真) によると明らかであるにもかかわらず、その行が DataTable にあることが検出されません。そのため、foreach ループに入ったり、必要なファイルを削除したりすることはありません。どうして???
ベースライン ファイルの情報 (最初の 4 行) はデータベースから取得されますが、ターゲット ファイルのフィールドはユーザーの入力に従って生成されます。ただし、DataTable を直接クエリしているので、情報がどこから来ているかがどのように問題になるかはわかりません...
アップデート
OK、ばかげたジェイミー・キーリングの提案に従った後、問題は 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 は null のままで、最後の行で実行時エラーが発生しています。IndexOutOfRangeException: The given DataRow is not in the current DataRowCollection
なぜこれが機能しないのですか?