【问题标题】:Removal of Duplicate Rows from Data table Based on Multiple columns基于多列从数据表中删除重复行
【发布时间】:2014-11-11 08:29:40
【问题描述】:

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

Barcode Itemid PacktypeId

1      100      1

1      100      2

1      100      3

1      100      1

1      100      3

只需要包含 packtypeid 1,2,3 的行,剩余的第 4 行和第 5 行应该被删除

我尝试过使用两种方法,但都没有得到更好的结果

数据表包含超过 10 列,但唯一列是“Barcode”、“ItemID”、“PackTypeID”

方法一:

 dt_Barcode = dt_Barcode.DefaultView.ToTable(true, "Barcode", "ItemID", "PackTypeID");

上述方法过滤的是行,但它只返回列 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++;
                }
               }

上述方法返回异常,就像位置 5 没有行一样

【问题讨论】:

    标签: c# datatable dataview


    【解决方案1】:

    方法三:

    我发现这个 Linq 方法非常有用,而不是尝试上述 2 种方法

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

    【讨论】:

    • 感谢您提供这个不错的解决方案!我不相信方法 1,它有时会永远存在并且不会回来..
    • 谢谢!此外,您可以使用不指定类型 T 的列索引:dt = dt.AsEnumerable().GroupBy(r =&gt; new { Field1 = r.ItemArray[0], Field2 = r.ItemArray[1] }).Select(g =&gt; g.First()).CopyToDataTable();
    【解决方案2】:

    这是因为您删除了行。

    如果您想保留相同的算法,而不是使用while (rowIndex &lt; i),请使用这种形式的循环:

    for (var rowIndex = rows.Count - 1; rowIndex >= 0; rowIndex--)
    {
        ...
    
        if (uniqueness.Contains(sb.ToString()))
        {
            rows.Remove(row);
            rowIndex--;
        }
        ...
    }
    

    【讨论】:

    • @Pradeep 请编辑您的问题,以便我可以为您现在提出的问题提供答案,而不是原始问题。
    【解决方案3】:
    public void RemoveDuplicatesFromDataTable(ref DataTable table, List<string> keyColumns)
            {
    
                Dictionary<string, string> uniquenessDict = new Dictionary<string, string>(table.Rows.Count);
                StringBuilder stringBuilder = null;
                int rowIndex = 0;
                DataRow row;
                DataRowCollection rows = table.Rows;
                string error = string.Empty;
    
                try
                {
                    while (rowIndex < rows.Count)
                    {
    
                        row = rows[rowIndex];
    
                        stringBuilder = new StringBuilder();
    
                        foreach (string colname in keyColumns)
                        {
                            try
                            {
                                if (row[colname].ToString() != string.Empty)
                                {
                                    stringBuilder.Append(((string)row[colname]));
                                }
                                else
                                {
                                    //If it comes here, means one of the keys are blank
                                    error += "One of the key values is blank.";
                                }
                            }
                            catch (Exception ss)
                            {
                                error += "Error " + ss.Message + ".";
                            }
                        }
    
                        if (uniquenessDict.ContainsKey(stringBuilder.ToString()))
                        {
                            rows.Remove(row);
                        }
                        else
                        {
                            uniquenessDict.Add(stringBuilder.ToString().Replace(",", ""), string.Empty);
                            rowIndex++;
                        }
    
                    }
                }
                catch (Exception ex)
                {
                    error = "Failed - " + ex.Message;
                }
    
                if(error != string.Empty)
                    Show`enter code here`(error);
            }
    

    【讨论】:

      猜你喜欢
      • 1970-01-01
      • 2015-07-26
      • 2021-04-28
      • 2016-11-01
      • 2018-12-27
      • 2021-11-03
      • 2013-06-13
      • 1970-01-01
      相关资源
      最近更新 更多