C# 基于多列从数据表中删除重复行

C# 基于多列从数据表中删除重复行,c#,datatable,dataview,C#,Datatable,Dataview,我有一个包含许多重复行的数据表,我需要根据多个列从数据表中筛选这些行,以在结果数据表中获得不同的行 Barcode Itemid PacktypeId 1 100 1 1 100 2 1 100 3 1 100 1 1 100 3 dt_Barcode = dt_Barcode.AsEnumerable().GroupBy(r => new { ItemID = r.F

我有一个包含许多重复行的数据表,我需要根据多个列从数据表中筛选这些行,以在结果数据表中获得不同的行

Barcode Itemid PacktypeId

1      100      1

1      100      2

1      100      3

1      100      1

1      100      3
     dt_Barcode = dt_Barcode.AsEnumerable().GroupBy(r => new { ItemID = r.Field<Int64>("ItemID"), PacktypeId = r.Field<Int32>("PackTypeID") }).Select(g => g.First()).CopyToDataTable(); 
只需删除包含packtypeid 1、2、3的行,其余第4行和第5行应删除

     dt_Barcode = dt_Barcode.AsEnumerable().GroupBy(r => new { ItemID = r.Field<Int64>("ItemID"), PacktypeId = r.Field<Int32>("PackTypeID") }).Select(g => g.First()).CopyToDataTable(); 
我试过使用两种方法,但都没有达到更好的效果

     dt_Barcode = dt_Barcode.AsEnumerable().GroupBy(r => new { ItemID = r.Field<Int64>("ItemID"), PacktypeId = r.Field<Int32>("PackTypeID") }).Select(g => g.First()).CopyToDataTable(); 
数据表包含10多列,但唯一的列是Barcode、ItemID、PackTypeID

     dt_Barcode = dt_Barcode.AsEnumerable().GroupBy(r => new { ItemID = r.Field<Int64>("ItemID"), PacktypeId = r.Field<Int32>("PackTypeID") }).Select(g => g.First()).CopyToDataTable(); 
方法1:

 dt_Barcode = dt_Barcode.DefaultView.ToTable(true, "Barcode", "ItemID", "PackTypeID");
     dt_Barcode = dt_Barcode.AsEnumerable().GroupBy(r => new { ItemID = r.Field<Int64>("ItemID"), PacktypeId = r.Field<Int32>("PackTypeID") }).Select(g => g.First()).CopyToDataTable(); 
上面的方法过滤行,但它只返回3列值,我需要整个10列值

Method-2:
                   List<string> keyColumns = new List<string>();
                   keyColumns.Add("Barcode");
                   keyColumns.Add("ItemID");
                   keyColumns.Add("PackTypeID");   
           RemoveDuplicates(DataTable table, List<string> keyColumns)
            {
            var uniqueness = new HashSet<string>();
            StringBuilder sb = new StringBuilder();
            int rowIndex = 0;
            DataRow row;
            DataRowCollection rows = table.Rows;             
            int i = rows.Count;
            while (rowIndex < i)
            {
                row = rows[rowIndex];
                sb.Length = 0;
                foreach (string colname in keyColumns)
                {
                    sb.Append(row[colname]);
                    sb.Append("|");
                }

                if (uniqueness.Contains(sb.ToString()))
                {
                    rows.Remove(row);
                }
                else
                {
                    uniqueness.Add(sb.ToString());
                    rowIndex++;
                }
               }
     dt_Barcode = dt_Barcode.AsEnumerable().GroupBy(r => new { ItemID = r.Field<Int64>("ItemID"), PacktypeId = r.Field<Int32>("PackTypeID") }).Select(g => g.First()).CopyToDataTable(); 

上面的方法返回异常,就像在位置5没有行一样。发生这种情况是因为您删除了行

     dt_Barcode = dt_Barcode.AsEnumerable().GroupBy(r => new { ItemID = r.Field<Int64>("ItemID"), PacktypeId = r.Field<Int32>("PackTypeID") }).Select(g => g.First()).CopyToDataTable(); 
如果要保留相同的算法,而不是使用while rowIndex
for (var rowIndex = rows.Count - 1; rowIndex >= 0; rowIndex--)
{
    ...

    if (uniqueness.Contains(sb.ToString()))
    {
        rows.Remove(row);
        rowIndex--;
    }
    ...
}
     dt_Barcode = dt_Barcode.AsEnumerable().GroupBy(r => new { ItemID = r.Field<Int64>("ItemID"), PacktypeId = r.Field<Int32>("PackTypeID") }).Select(g => g.First()).CopyToDataTable(); 

这是因为您删除了行

     dt_Barcode = dt_Barcode.AsEnumerable().GroupBy(r => new { ItemID = r.Field<Int64>("ItemID"), PacktypeId = r.Field<Int32>("PackTypeID") }).Select(g => g.First()).CopyToDataTable(); 
如果要保留相同的算法,而不是使用while rowIndex
for (var rowIndex = rows.Count - 1; rowIndex >= 0; rowIndex--)
{
    ...

    if (uniqueness.Contains(sb.ToString()))
    {
        rows.Remove(row);
        rowIndex--;
    }
    ...
}
     dt_Barcode = dt_Barcode.AsEnumerable().GroupBy(r => new { ItemID = r.Field<Int64>("ItemID"), PacktypeId = r.Field<Int32>("PackTypeID") }).Select(g => g.First()).CopyToDataTable(); 
方法3:

     dt_Barcode = dt_Barcode.AsEnumerable().GroupBy(r => new { ItemID = r.Field<Int64>("ItemID"), PacktypeId = r.Field<Int32>("PackTypeID") }).Select(g => g.First()).CopyToDataTable(); 
我没有尝试以上两种方法,而是发现这个Linq方法非常有用

     dt_Barcode = dt_Barcode.AsEnumerable().GroupBy(r => new { ItemID = r.Field<Int64>("ItemID"), PacktypeId = r.Field<Int32>("PackTypeID") }).Select(g => g.First()).CopyToDataTable(); 
方法3:

     dt_Barcode = dt_Barcode.AsEnumerable().GroupBy(r => new { ItemID = r.Field<Int64>("ItemID"), PacktypeId = r.Field<Int32>("PackTypeID") }).Select(g => g.First()).CopyToDataTable(); 
我没有尝试以上两种方法,而是发现这个Linq方法非常有用

     dt_Barcode = dt_Barcode.AsEnumerable().GroupBy(r => new { ItemID = r.Field<Int64>("ItemID"), PacktypeId = r.Field<Int32>("PackTypeID") }).Select(g => g.First()).CopyToDataTable(); 

@Pradeep请编辑您的问题,这样我就可以为您现在提出的问题而不是原始问题提供答案。@Pradeep请编辑您的问题,这样我就可以为您现在提出的问题而不是原始问题提供答案。谢谢您提供了这个很好的解决方案!我不相信方法1,它有时会永远消失,不再回来。谢谢!此外,您还可以在不指定类型T的情况下与列索引一起使用:dt=dt.AsEnumerable.GroupByr=>new{Field1=r.ItemArray[0],Field2=r.ItemArray[1]}。Selectg=>g.First.CopyToDataTable;感谢您提供了这个很好的解决方案!我不相信方法1,它有时会永远消失,不再回来。谢谢!此外,您还可以在不指定类型T的情况下与列索引一起使用:dt=dt.AsEnumerable.GroupByr=>new{Field1=r.ItemArray[0],Field2=r.ItemArray[1]}。Selectg=>g.First.CopyToDataTable;