【问题标题】:How to delete rows from DataTable with LINQ?如何使用 LINQ 从 DataTable 中删除行?
【发布时间】:2013-09-22 03:50:22
【问题描述】:

我有以下代码从 DataTable 中删除行:

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

上面的代码工作正常。如何将此代码转换LINQ

【问题讨论】:

  • 仅供参考 linq 在内部也使用循环!
  • 你为什么喜欢在 linq 中这样做?
  • @KingKing 为什么? rowsDataRow[] 是什么阻止你删除?
  • @SriramSakthivel 看的时候太不小心了,其实row.Delete()会修改集合dTable.Rows而不是rows
  • @KingKing 发生了..

标签: c# asp.net linq


【解决方案1】:

LINQ 不用于删除或修改 - 它用于查询数据。使用 LINQ,您可以选择应该删除的数据,然后手动删除这些数据(例如,在 foreach 循环中或使用 ForEach 列表扩展名):

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

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

更新:同样使用 LINQ to DataSet,您可以选择应该保留在表中的所有行并从这些行创建新的 DataTable:

var table = dTable.AsEnumerable()
                  .Where(r => r.Field<string>("col1") != "ali")
                  .CopyToDataTable();

【讨论】:

  • 错误:集合已修改;枚举操作可能不会执行。
  • @SamieyMehdi 抱歉,已修复。还添加了替代解决方案来展示 LINQ 的工作原理 - 您可以选择要删除的内容,或者选择应该保留的内容。
  • @SamieyMehdi 我完全确定它有效。请检查您的代码 - 可能您缺少 ToList() 电话
  • @SamieyMehdi Collection was modified 出现错误是因为如果在使用枚举器时修改了表,则数据表枚举器会引发异常(列表也是如此,当您尝试在 foreach 中修改它们时)。
  • @SamieyMehdi 怎么不工作? row.Delete() 不会修改 query.ToList(),所以它应该可以工作。
【解决方案2】:

试试这个带有扩展方法的内联 lambda 代码:

dTable.AsEnumerable().Where(r => r.Field("col1") == "ali").ToList().ForEach(row => row.Delete()); dTable.AcceptChanges();

【讨论】:

    【解决方案3】:

    你使用 for 循环或 while 循环来删除行但不是 foreach

    下面是非linq解决方案

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

    LINQ

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

    【讨论】:

    • 这会删除所有else。即使您反转条件,您现在也复制了一大堆数据,假设要保留的行比要删除的行多得多。
    • @SamieyMehdi 你甚至没有注意到Servy's comment?如果您的 DataTable 很大,而您只需要删除一些行,那么这样做将非常低效。
    • 更不用说这个问题专门要求一个 LINQ 解决方案,而这没有(但这比前面提到的低效方法问题少)。
    【解决方案4】:
    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);
    }
    

    【讨论】:

      【解决方案5】:

      试试这个

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

      【讨论】:

        【解决方案6】:

        我搜索了很多(好吧,超过四个 Google 搜索)以寻找解决方案,最后我最终(在 Sergey Berezovskiy 的帖子中)收集到 LINQ 不会删除 - 所以你使用 LINQ 来选择您希望通过正在使用的数据库技术的“常规”机制删除和删除它们的行。似乎让所有关于 LINQ 的与数据库无关的宣传变得非常愚蠢?

        这确实有效,尽管通过更多的实验可以将两个“For Each”循环减少到一个。

        我有一个属性表,我想在其中删除具有特定 ObjectType(第一个键域)的选定属性名称(第三个键域)的所有条目,我想出了这个。

        仅供参考,REPLY 对象有点像 Error 对象 - 我只是打包错误消息、二进制 Pass/fail 标志和其他一些东西,这样我就可以从查询中传回大量内容并(最终)显示错误给用户。

          ' <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
        

        【讨论】:

          【解决方案7】:
          dTable.Rows.Remove(dTable.AsEnumerable().Where(r => r.Field<string>("col1") == "Ali").FirstOrDefault());
          

          【讨论】:

          • 如果有解释,以及与 OP 的字段/值匹配的代码,效果会更好。
          • 这只会从数据表中删除一行
          猜你喜欢
          • 1970-01-01
          • 1970-01-01
          • 1970-01-01
          • 2011-10-24
          • 1970-01-01
          • 2015-06-13
          • 1970-01-01
          • 1970-01-01
          • 1970-01-01
          相关资源
          最近更新 更多