如何检查数据集中的重复行?

时间:2014-03-05 12:08:27

标签: c# dataset

enter image description here

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

以下是我的代码,请帮助

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

5 个答案:

答案 0 :(得分:3)

您的代码无效,因为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);

答案 1 :(得分:1)

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

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

答案 2 :(得分:0)

我认为你必须改变你的逻辑。您不会将行添加到hTable,因此永远不会重复。我想你最后必须显示消息,否则列表还不完整。

正如其他人所说,你确实需要Sergeys的回答让比较工作。如果你有这个,那么这段代码将解决其他逻辑问题。

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

答案 3 :(得分:0)

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

作为旁注,您不能只将DataRow与另一个DataRow进行比较,它将使用默认的相等比较(使用IEqualityComparer实现)并有效归结为引用相等性检查,其中没有任何行彼此相等。

在某个地方,您可以实现自己的IEqualityCompariosn,也可以只编写自定义方法来检查每行的值。

答案 4 :(得分:0)

以上是我上述问题的答案

您可以检查数据集中的重复行..它运行正常尝试。

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