web-dev-qa-db-fra.com

Comment supprimer des lignes de DataTable avec LINQ?

J'ai le code suivant pour supprimer des lignes de DataTable: 

var rows = dTable.Select("col1 ='ALi'");
foreach (var row in rows)
   row.Delete();

le code ci-dessus fonctionne bien. comment convertir ce code enLINQ?

14
Samiey Mehdi

LINQ n'est pas destiné à la suppression ou à la modification - il est destiné à querying data. Avec LINQ, vous pouvez sélectionner les données à supprimer, puis les supprimer manuellement (par exemple, dans une boucle foreach ou avec l’extension de liste ForEach):

var query = dTable.AsEnumerable().Where(r => r.Field<string>("col1") == "ALi");

foreach(var row in query.ToList())
   row.Delete();

UPDATE: De même avec LINQ to DataSet, vous pouvez sélectionner toutes les lignes qui doivent rester dans la table et créer un nouveau DataTable à partir de ces lignes:

var table = dTable.AsEnumerable()
                  .Where(r => r.Field<string>("col1") != "ALi")
                  .CopyToDataTable();
27
Sergey Berezovskiy

Essayez ce code lambda en ligne avec des méthodes d’extension: 

dTable.AsEnumerable().Where(r => r.Field<string>("col1") == "ALi").ToList().ForEach(row => row.Delete());
8
Mohamed Salemyan

vous utilisez les boucles for ou while pour supprimer des lignes, mais pas foreach

ci-dessous solution non linq

dTable= dTable.Select("col1 <> 'ALi'").CopyToDataTable();

LINQ

dTable = dTable.AsEnumerable().Where(r => r.Field<string>("col1") != "ALi").CopyToDataTable();
1
Damith

J'ai cherché loin (bien, plus de quatre recherches sur Google) pour trouver une solution à ce problème et finalement j'ai glané (voir plus haut dans l'article de Sergey Berezovskiy) que LINQ ne supprime pas - vous utilisez donc LINQ pour sélectionner les lignes que vous souhaitez voulez vous en débarrasser et les supprimer par le mécanisme «habituel» de la technologie de base de données utilisée. Semble faire toute cette propagande agnostique base de données sur LINQ assez ridicule?

Cela fonctionne, mais avec un peu plus d’expérimentation, on pourrait peut-être réduire les deux boucles «For Each» à une.

J'avais une table de propriétés où je voulais supprimer toutes les entrées avec un nom de propriété choisi (3ème champ de clé) pour un ObjectType particulier (1er champ de clé) et je l'ai trouvé.

Pour info, l’objet REPLY ressemble un peu à l’objet Error - je mets juste en package les messages d’erreur, un indicateur binaire Pass/fail et quelques autres éléments afin de pouvoir renvoyer des charges de données provenant d’une requête et (éventuellement) afficher l’erreur à l’utilisateur .

  ' <summary>
  ' The user has decided they don't want a particular property type so we delete all
  ' properties of that type in the table - belonging to any object of that ObjectType
  ' </summary>
  ' <param name="sObjectType"></param>
  ' <param name="sName"></param>
  ' <returns></returns>
  ' <remarks></remarks>
  Public Function DeleteAllPropsByName(sObjectType As String, sName As String) As Reply

    ' Default answer is 'OK'
    DeleteAllPropsByName = New Reply(True)

    Dim T As DataTable = mDB.DataTableImage(msTableName)
    Dim q = From rw In T.AsEnumerable
            Where rw.Field(Of String)("ObjectType") = sObjectType _
            And rw.Field(Of String)("PropName") = sName

    ' Somewhere to remember our list of target rows to delete
    Dim rows As New List(Of DataRow)

    For Each row In q
      '
      ' LINQ doesn't delete so we need to delete from the Datatable directly.
      ' If we delete here we get the collection modified error so we have to save 
      ' the datarows to ANOTHER list and then delete them from there.
      rows.Add(row)

    Next

    For Each rw As DataRow In rows
      '
      ' Call the Delete routine in my table class passing it the 
      ' primary key of the row to delete
      '
      DeleteAllPropsByName = gDB.Table(msTableName).Delete( _
                                  rw.Item("ObjectType").ToString, _
                                  CInt(rw.Item("ObjectID")), _
                                  rw.Item("PropName").ToString)

      If Not DeleteAllPropsByName.OK Then
        ' The reply object (in DeleteAllPropsByName) has all the error info so we can just
        ' exit and return it if the delete failed.
        Exit Function
      End If

    Next

  End Function
0
Captain Fantastic
var results = from row in dTable.Tables["tablename"].AsEnumerable()
          where row.Field<string>("Col1") == "ALi" 
          select row;
foreach (DataRow row in results)
{
   dTable.Tables["tablename"].Remove(row);
}
0
Suraj Singh

Essaye ça

DataRow[] rows;
rows=dataTable.Select("UserName = 'ABC'"); // UserName is Column Name
foreach(DataRow r in rows)
r.Delete();
0
Golda