カスタム条件に適合するDataTable行のループ内の特定のDataRowsを削除するにはどうすればいいですか? (LINQを使用しない場合)
ありがとう
「delete」の意味によって異なります
それらを削除済みとしてマークする場合、ループ内で訪問するときに各行でDelete()
メソッドを呼び出すだけです。次に、データテーブルでAcceptChanges()
を呼び出して、削除を完了させる必要があります-おそらくデータベースを更新した後(関係する場合)。
foreach( DataRow row in someTable.Rows )
{
if( /* your condition here */ )
row.Delete();
}
someTable.AcceptChanges();
DataTableから削除する場合は、2つのパスで削除する必要があります:
List<DataRow> rowsToDelete = new List<DataRow>();
foreach( DataRow row in someTable.Rows )
{
if( /* your condition here */ )
{
rowsToDelete.Add( row );
}
}
foreach( DataRow row in rowsToDelete )
{
someTable.Rows.Remove( row );
}
行を削除するには、常に最初の方法を使用できることに注意してください-行をDeleted
としてマークしてから変更を受け入れると、テーブルから自動的に削除されます。ただし、DataRow
コレクションからRows
オブジェクトを単純に削除する方がより明確で効率的な場合があります。
この例のようなものを試してください
DataTable table = new DataTable();
table.Columns.Add("Foo",typeof(int));
for (int i = 0; i < 10; i++)
table.Rows.Add(i);
for (int i = table.Rows.Count -1; i >=0; i--)
{
// sample removes all even foos
if ((int)table.Rows[i]["Foo"] % 2 == 0)
table.Rows.RemoveAt(i);
}
他の方法は
DataRow[] DrArrCheck = DataTableName.Select("ID > 0");
foreach(DataRow DrCheck in DrArrCheck)
{
DataTableName.Rows.Remove(DrCheck);
}
上記で提案されているものよりも短い解決策が必要な場合は、結果のリストをループして、sub(x)
のようなlambdaを使用してみてください。これらの各行を削除します。
dt.Select("Column1 > 0").ToList.ForEach(Sub(x) dt.Rows.Remove(x))
複数の行(たとえば、100,000から50,000)を削除するには、datatable.Rows.Remove(row)またはrow.Delete()を実行するよりも、データベースをコピーする方がはるかに高速です。例えば:
DataRow[] rowsToKeep = datatable.Select("ID > 50000");
DataTable tempDataTable= rowsToKeep.CopyToDataTable;
dataTable.Clear();
dataTable.Merge(tempDataTable);
tempDataTable.Dispose();
public static void DeleteRowsFromDataTable(DataTable dataTable, string columnName, string columnValue)
{
IEnumerable<DataRow> dataRows = (from t in dataTable.AsEnumerable()
where t.Field<string>(columnName) == columnValue
select t);
foreach (DataRow row in dataRows)
dataTable.Rows.Remove(row);
}
select()の結果を反復処理してみてください。これは他の回答とかなり似ていますが、最も直接的なものだと思います
DataRow[] r = table.Select();
for (int i = 0; i < r.Length; i++)
{
if (i % 2 == 0)
r[i].Delete();
}
私は常にLBushkinの「2フェーズ」アプローチを使用し、そのための関数を記述することは最終的に価値があると判断しました。
public delegate bool DataRowComparer(DataRow dr);
public static void RemoveDataRows(DataTable table, DataRowComparer drc)
{
List<DataRow> RowsToRemove = new List<DataRow>();
foreach (DataRow dr in table.Rows)
if (drc(dr))
RowsToRemove.Add(dr);
foreach (DataRow dr in RowsToRemove)
table.Rows.Remove(dr);
}
そして今、私は1行のコードで行を削除できます(たとえば):
RemoveDataRows(dt, row => row["StringVal"].ToString() == "B" && (Int16)(row["NumberVal"]) >= 4);
これが誰にも役立つ場合...
(さらに短縮する方法はありがたいです。)