Лучший способ удалить повторяющиеся записи из таблицы данных

Каков наилучший способ удалить повторяющиеся записи из таблицы данных?

11 ответов

Решение

Удалить дубликаты

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

Делать dtEmp на вашей текущей рабочей DataTable:

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

Мило.

Простой способ будет:

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

Этот пост касается только выборки Различает строки из таблицы данных на основе нескольких столбцов.

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

Вам нужно вызвать этот метод, и вам нужно присвоить значение datatable. В приведенном выше коде у нас есть RNORFQNo, PartNo,RFQ id,ItemId, RNONo, QUantity, NSNNO, UOMName,MOQ и Item Description в виде столбца, для которого нам нужны разные значения.

Вот простой и быстрый способ использования 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;
}

Нажмите, чтобы посетить мой блог для более подробной информации

Существует простой способ с использованием метода Linq GroupBy.

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);
    /* 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();
        }
    }

Полностью отдельные строки:

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

Различаются по определенным строкам (обратите внимание, что столбцы, упомянутые в "DifferentCulumnNames", будут возвращены в результирующей DataTable):

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

Чтобы отделить все столбцы с данными, вы можете легко получить имена столбцов в массиве строк.

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.

Вы можете использовать метод DefaultView.ToTable объекта DataTable, чтобы выполнить фильтрацию следующим образом (адаптироваться к 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

Я бы предпочел это, так как это быстрее, чем цикл 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();
Другие вопросы по тегам