【问题标题】:Best way to remove duplicate entries from a data table从数据表中删除重复条目的最佳方法
【发布时间】:2011-05-23 20:45:55
【问题描述】:

从数据表中删除重复条目的最佳方法是什么?

【问题讨论】:

标签: c# .net datatable duplicate-data


【解决方案1】:

在您当前工作的 DataTable 上执行 dtEmp

DataTable distinctTable = dtEmp.DefaultView.ToTable( /*distinct*/ true);

很好看。

【讨论】:

  • 这个答案值得更多关注,这正是我所需要的,而且比构建哈希表/字典/任何东西都简单,只要您只需要过滤精确的重复项。
  • 注意此解决方案的性能。在我的实现中,ToTable() 非常慢,花费的时间比获取数据的原始查询长 30 倍。
  • 这非常好,但对于较大的数据表,它可能非常非常慢。我在一个包含 80 万条记录、大约 20 列的数据表上尝试了这个,它在我的 8 vCPU Windows 7 PC 上运行了几分钟(我什至没有等待它完成)。
【解决方案2】:

删除重复项

public DataTable RemoveDuplicateRows(DataTable dTable, string colName)
{
   Hashtable hTable = new Hashtable();
   ArrayList duplicateList = new ArrayList();

   //Add list of all the unique item value to hashtable, which stores combination of key, value pair.
   //And add duplicate item value in arraylist.
   foreach (DataRow drow in dTable.Rows)
   {
      if (hTable.Contains(drow[colName]))
         duplicateList.Add(drow);
      else
         hTable.Add(drow[colName], string.Empty); 
   }

   //Removing a list of duplicate items from datatable.
   foreach (DataRow dRow in duplicateList)
      dTable.Rows.Remove(dRow);

   //Datatable which contains unique records will be return as output.
      return dTable;
}

以下链接

http://www.dotnetspider.com/resources/4535-Remove-duplicate-records-from-table.aspx

http://www.dotnetspark.com/kb/94-remove-duplicate-rows-value-from-datatable.aspx

用于删除列中的重复项

http://dotnetguts.blogspot.com/2007/02/removing-duplicate-records-from.html

【讨论】:

  • :我怎样才能为多个列做到这一点。我尝试包括 string[] colName.But Table.Rows.Remove(dRow);抛出错误,如“给定的 DataRow 不在当前 DataRowCollection 中”。请提出建议。
  • 您必须在更多级别上逐步修改 foreach。但是,使用 Linq 可能更容易。 stackoverflow.com/questions/8939516/…
  • 来自 dotnetspark 的链接对我有用,因为只有当 2 列的行匹配时我才需要删除行。但这仅适用于一种类型,但对我来说很好!
  • 此解决方案基于列。也许一列是相同的,但其他列不一样。
  • 工作愉快,谢谢
【解决方案3】:

一个简单的方法是:

 var newDt= dt.AsEnumerable()
                 .GroupBy(x => x.Field<int>("ColumnName"))
                 .Select(y => y.First())
                 .CopyToDataTable();

【讨论】:

  • 这是给我的。在不删除其他列的情况下,只需忽略提到的列名的重复记录。
【解决方案4】:

这篇文章是关于基于多列从数据表中仅获取不同的行。

Public coid removeDuplicatesRows(DataTable dt)
{
  DataTable uniqueCols = dt.DefaultView.ToTable(true, "RNORFQNo", "ManufacturerPartNo",  "RNORFQId", "ItemId", "RNONo", "Quantity", "NSNNo", "UOMName", "MOQ", "ItemDescription");
} 

你需要调用这个方法,你需要给数据表赋值。 在上面的代码中,我们将 RNORFQNo、PartNo、RFQ id、ItemId、RNONo、Quantity、NSNNO、UOMName、MOQ 和 Item Description 作为我们想要不同值的列。

【讨论】:

    【解决方案5】:

    这是使用AsEnumerable().Distinct()的简单快捷方式

    private DataTable RemoveDuplicatesRecords(DataTable dt)
    {
        //Returns just 5 unique rows
        var UniqueRows = dt.AsEnumerable().Distinct(DataRowComparer.Default);
        DataTable dt2 = UniqueRows.CopyToDataTable();
        return dt2;
    }
    

    【讨论】:

      【解决方案6】:

      有一个使用 Linq GroupBy Method 的简单方法。

      var duplicateValues = dt.AsEnumerable() 
      
              .GroupBy(row => row[0]) 
      
              .Where(group => (group.Count() == 1 || group.Count() > 1)) 
      
              .Select(g => g.Key); 
      
      
      
      foreach (var d in duplicateValues)
      
              Console.WriteLine(d);
      

      【讨论】:

      • 我猜你不需要按 count() == 1 分组,否则你会得到所有行。
      【解决方案7】:
          /* To eliminate Duplicate rows */
          private void RemoveDuplicates(DataTable dt)
          {
      
              if (dt.Rows.Count > 0)
              {
                  for (int i = dt.Rows.Count - 1; i >= 0; i--)
                  {
                      if (i == 0)
                      {
                          break;
                      }
                      for (int j = i - 1; j >= 0; j--)
                      {
                          if (Convert.ToInt32(dt.Rows[i]["ID"]) == Convert.ToInt32(dt.Rows[j]["ID"]) && dt.Rows[i]["Name"].ToString() == dt.Rows[j]["Name"].ToString())
                          {
                              dt.Rows[i].Delete();
                              break;
                          }
                      }
                  }
                  dt.AcceptChanges();
              }
          }
      

      【讨论】:

        【解决方案8】:

        完全不同的行:

        public static DataTable Dictinct(this dt) => dt.DefaultView.ToTable(true);
        

        按特定行区分(请注意,“distinctClumnNames”中提到的列将在结果数据表中返回):

        public static DataTable Dictinct(this dt, params string[] distinctColumnNames) => 
        dt.DefaultView.ToTable(true, distinctColumnNames);
        

        按特定列区分(保留给定 DataTable 中的所有列):

        public static void Distinct(this DataTable dataTable, string distinctColumnName)
        {
            var distinctResult = new DataTable();
            distinctResult.Merge(
                             .GroupBy(row => row.Field<object>(distinctColumnName))
                             .Select(group => group.First())
                             .CopyToDataTable()
                    );
        
            if (distinctResult.DefaultView.Count < dataTable.DefaultView.Count)
            {
                dataTable.Clear();
                dataTable.Merge(distinctResult);
                dataTable.AcceptChanges();
            }
        }
        

        【讨论】:

          【解决方案9】:

          您可以使用 DataTable 的 DefaultView.ToTable 方法进行这样的过滤(适应 C#):

           Public Sub RemoveDuplicateRows(ByRef rDataTable As DataTable)
              Dim pNewDataTable As DataTable
              Dim pCurrentRowCopy As DataRow
              Dim pColumnList As New List(Of String)
              Dim pColumn As DataColumn
          
              'Build column list
              For Each pColumn In rDataTable.Columns
                  pColumnList.Add(pColumn.ColumnName)
              Next
          
              'Filter by all columns
              pNewDataTable = rDataTable.DefaultView.ToTable(True, pColumnList.ToArray)
          
              rDataTable = rDataTable.Clone
          
              'Import rows into original table structure
              For Each pCurrentRowCopy In pNewDataTable.Rows
                  rDataTable.ImportRow(pCurrentRowCopy)
              Next
          End Sub
          

          【讨论】:

            【解决方案10】:

            为了区分所有数据表列,您可以轻松检索字符串数组中列的名称

            public static DataTable RemoveDuplicateRows(this DataTable dataTable)
            {
                List<string> columnNames = new List<string>();
                foreach (DataColumn col in dataTable.Columns)
                {
                    columnNames.Add(col.ColumnName);
                }
                return dataTable.DefaultView.ToTable(true, columnNames.Select(c => c.ToString()).ToArray());
            }
            

            如您所见,我想将其用作 DataTable 类的扩展

            【讨论】:

              【解决方案11】:

              我更喜欢这个,因为它比 DefaultView.ToTable 和 foreach 循环删除重复项更快。使用它,我们也可以在多个列上进行分组。

              DataTable distinctDT = (from rows in dt.AsEnumerable() 
              group rows by new { ColA = rows["ColA"], ColB = rows["ColB"]} into grp
              select grp.First()).CopyToDataTable();
              

              【讨论】:

                猜你喜欢
                • 2018-11-01
                • 2010-09-21
                • 2020-11-22
                • 1970-01-01
                • 2020-08-03
                • 2021-05-19
                • 1970-01-01
                • 2016-05-22
                • 2018-03-13
                相关资源
                最近更新 更多