Comment puis-je supprimer des DataRows spécifiques dans une boucle de lignes DataTable qui répondent à une condition personnalisée - les cases disent que les lignes ont un index de nombre pair -? (Sans utiliser LINQ)
Merci
Cela dépend de ce que vous entendez par "supprimer".
Si vous voulez les marquer comme supprimés , appelez simplement la méthode Delete()
sur chaque ligne pendant que vous la visitez dans votre boucle. Vous devez ensuite appeler AcceptChanges()
sur la table de données pour finaliser la suppression - sans doute après avoir mis à jour votre base de données (le cas échéant).
foreach( DataRow row in someTable.Rows )
{
if( /* your condition here */ )
row.Delete();
}
someTable.AcceptChanges();
Si vous voulez le supprimer du DataTable, vous devez le faire en deux passes:
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 );
}
Il convient de souligner que vous pouvez toujours utiliser la première méthode pour supprimer des lignes, car le marquage des lignes comme Deleted
, puis l'acceptation des modifications les supprimera automatiquement du tableau. Mais, il est parfois plus clair et plus efficace de simplement supprimer les objets DataRow
de la collection Rows
.
Essayez quelque chose comme cet exemple
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);
}
L'autre façon est
DataRow[] DrArrCheck = DataTableName.Select("ID > 0");
foreach(DataRow DrCheck in DrArrCheck)
{
DataTableName.Rows.Remove(DrCheck);
}
Si vous voulez une solution plus courte que celles proposées ci-dessus, essayez de parcourir la liste des résultats et d'utiliser un lambda comme sub(x)
pour supprimer chacune de ces lignes.
dt.Select("Column1 > 0").ToList.ForEach(Sub(x) dt.Rows.Remove(x))
Pour supprimer plusieurs lignes (par exemple 50 000 sur 100 000), il est beaucoup plus rapide de copier la base de données que de faire datatable.Rows.Remove (row) ou row.Delete (). Par exemple:
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);
}
essayez d'itérer sur le résultat de Select (). Ceci est assez similaire aux autres réponses, mais je le trouve le plus direct
DataRow[] r = table.Select();
for (int i = 0; i < r.Length; i++)
{
if (i % 2 == 0)
r[i].Delete();
}
J'ai toujours utilisé l'approche "en deux phases" de LBushkin et j'ai finalement décidé qu'il valait la peine d'écrire une fonction pour cela:
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);
}
Et maintenant, je peux supprimer des lignes avec une ligne de code (par exemple):
RemoveDataRows(dt, row => row["StringVal"].ToString() == "B" && (Int16)(row["NumberVal"]) >= 4);
Au cas où cela aiderait quelqu'un ...
(Et tout moyen d'abréger davantage est apprécié.)