【问题标题】:How to check duplicate rows in dataset?如何检查数据集中的重复行?
【发布时间】:2014-03-05 12:08:26
【问题描述】:

我有一个包含重复行的数据集,我希望在存在重复行时执行我的错误消息。

下面是我的代码,请帮忙

DataSet dsXml = new DataSet();

dsXml.ReadXml(new XmlTextReader(new StringReader(xml)));
Hashtable hTable = new Hashtable();
ArrayList duplicateList = new ArrayList();
foreach (DataRow drow in dsXml.Tables[0].Rows)
{
    if (hTable.Contains(drow))
    {
        duplicateList.Add(drow);
    }
    else
    {
        script.Append("alert('Error - There are some Duplicate entries.'); ");
        ErrorOcc = true;
        if (ErrorOcc)
        {
            this.ScriptOutput = script + " ValidateBeforeSaving = false;";
            this.StayContent = "yes";
            return;
        }
    }
}

【问题讨论】:

  • 您需要更多帮助吗?如果没有,请将此问题标记为已回答。

标签: c# dataset


【解决方案1】:

您的代码不起作用,因为DataRow 实例将通过引用进行比较,而不是比较它们的字段。您可以使用自定义比较器:

public class CustomDataRowComparer : IEqualityComparer<DataRow>
{
    public bool Equals(DataRow x, DataRow y)
    {
        if (x.ItemArray.Length != y.ItemArray.Length)
            return false;

        for (int i = 0; i < x.ItemArray.Length; i++)                            
            if (!x[i].Equals(y[i]))
                return false;            

        return true;
    }

    public int GetHashCode(DataRow obj)
    {
        int hash = 17;
        foreach (object field in obj.ItemArray)
            hash = hash * 19 + field.GetHashCode();

        return hash;
    }
}

或使用现有的DataRowComparer,它通过基于值的比较来比较DataRow 对象的等价性:

HashSet<DataRow> set = new HashSet<DataRow>(DataRowComparer.Default);
// or: new HashSet<DataRow>(new CustomDataRowComparer());

foreach (DataRow row in dsXml.Tables[0].Rows)
{
    if (!set.Add(row))
        // duplicate row
}

您还可以使用 Linq to DataSet 查询检查是否存在重复行:

var duplicatedRowsExist = dsXml.Tables[0].AsEnumerable()
                               .GroupBy(r => r, DataRowComparer.Default)
                               .Any(g => g.Count() > 1);

【讨论】:

    【解决方案2】:

    您必须比较行的内容,而不是行本身。应该这样做:

    var hasDupes = dsXml.Tables[0].Rows
        .AsEnumerable()
        .GroupBy(row => new 
         { 
               row.Field<string>("Title"), 
               row.Field<string>("Address"), 
               row.Field<string>("State"), 
               row.Field<string>("City"), 
               row.Field<int>("Status"), 
               row.Field<int>("CreatedBy"), 
               row.Field<int>("UpdatedBy") 
         })
        .Where(g => g.Count() > 1)
        .Any();
    
    if(hasDupes)
      //Show error message
    

    【讨论】:

      【解决方案3】:

      我认为你必须稍微改变你的逻辑。您不会将该行添加到 hTable,因此永远不会有重复项。而且我猜你必须在最后显示消息,否则列表将不完整。

      正如其他人所说,您确实需要 Sergey 的回答才能进行比较。如果你已经涵盖了,这段代码将解决其他逻辑问题。

      foreach (DataRow drow in dsXml.Tables[0].Rows)
      {
          if (!hTable.Contains(drow))
          {
              hTable.Contains(drow);
              hTable.Add(drow);
          }
          else
          {
              duplicateList.Add(drow);
          }
      }
      
      script.Append("alert('Error - There are some Duplicate entries.'); ");
      ErrorOcc = true;
      if (ErrorOcc)
      {
          this.ScriptOutput = script + " ValidateBeforeSaving = false;";
          this.StayContent = "yes";
          return;
      }
      

      【讨论】:

      • 这将使用默认的DataRow相等比较
      • @Simon:没错,我看到了 Sergey 的出色回答。尽管如此,即使实现了代码,代码也很糟糕。我建议 OP 将两个答案合并为一个。
      • @Simon:将答案更改为包含对 Sergeys 答案的引用。
      【解决方案4】:

      首先,您需要定义行之间的比较。当您创建 hTable 时,它会显示其中没有任何内容,因此 hTable.Contains 调用总是会返回 false。

      附带说明,您不能只将DataRow 与另一个DataRow 进行比较,它将使用默认的相等比较(使用 IEqualityComparer 实现)并有效地归结为引用相等检查,这都不是行将彼此相等。

      在某个地方,您可以实现自己的IEqualityCompariosn,或者简单地编写一个自定义方法来检查每一行的值。

      【讨论】:

        【解决方案5】:

        这是我上述问题的答案

        您可以检查数据集中的重复行。它工作正常,试试吧。

                        DataSet dsXml = new DataSet();
                        dsXml.ReadXml(new XmlTextReader(new StringReader(xml)));
        
                        List<string> duplicateList = new List<string>();
                        foreach (DataRow drow in dsXml.Tables[0].Rows)
                        {
                            string strr = "";
        
                            for (int j = 0; j < dsXml.Tables[0].Columns.Count; j++ )
                            {
                                strr += drow[j];
                            }
        
                            if (!duplicateList.Contains(strr))
                            {
                                duplicateList.Add(strr);
                            }
                            else
                            {
                                script.Append("alert('Error - There are some Duplicate entries.'); ");
                                ErrorOcc = true;
                                if (ErrorOcc)
                                {
                                    this.ScriptOutput = script + " ValidateBeforeSaving = false;";
                                    this.StayContent = "yes";
                                    return;
                                }
                            }
                        }
        

        【讨论】:

          猜你喜欢
          • 1970-01-01
          • 1970-01-01
          • 2012-12-27
          • 2020-02-25
          • 1970-01-01
          • 2014-04-07
          • 2020-03-22
          • 1970-01-01
          • 1970-01-01
          相关资源
          最近更新 更多