web-dev-qa-db-fra.com

Comment supprimer plusieurs lignes dans un DataTable?

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

30
pencilCake

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.

57
LBushkin

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);
}
9
Anthony Pegram

L'autre façon est

    DataRow[] DrArrCheck = DataTableName.Select("ID > 0");
    foreach(DataRow DrCheck in DrArrCheck)
    {
        DataTableName.Rows.Remove(DrCheck);
    }
4
BharathiNathan

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))
4
Sergey

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();
1
tval
 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);
        }
1
Vin

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();
}
0
Kleinux

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é.)

0
user2524845