【问题标题】:c# How to find duplicate records in a dataset that contains many datatables?c#如何在包含许多数据表的数据集中查找重复记录?
【发布时间】:2020-05-07 20:31:41
【问题描述】:

我有一个包含许多数据表的数据集(至少一个表,可能更多)。有没有一种简单的方法来检查整个 DataSet 是否有重复记录? 通过重复,我的意思是: 每张表代表一个Student对象,有StudentId、StudentName、NumberId三列(本项目中Students可以属于Numbers)。我需要一种方法来查看同一个 Student 是否存在于两个或多个表中,也就是说,同一个 StudentId 是否出现在任何表的多行中?
我试过了——

protected void CheckForDuplicateStudents()
{
DataSet setStudents = new DataSet();
foreach (GridViewRow gvr in grdNumbers.Rows)//grdNumbers on html page
    {
        int numberId = int.Parse(grdNumbers.DataKeys[gvr.RowIndex].Value.ToString());

        //for each row in the grid, get the student enrollent as a dt
        //put each dt into the dset
        DataTable tblRoster = PerformanceAccess.GetStudentsInNumber(numberId);

        setStudents.Tables.Add(tblRoster);
    } 

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

//do stuff here if query returns any duplicate records
}

但据我了解,此 LINQ 查询(和类似查询)仅检查单个数据表中的重复值,而不检查集合中的所有表。

有没有直接的方法来做到这一点?

编辑——我要澄清一下,每个表都有多行,其中每一行代表一个学生

`

【问题讨论】:

  • 我不明白你的配置。 table 的目的是存储多条记录,其中包含定义要存储在那里的实体(多个)的数据。我了解到您有多个表,每个表都存储一个学生记录。对吗?
  • @Steve - 很抱歉,如果不清楚 - 每张桌子都会有多个学生。如果相关,该数据集表示一个 Performance 的整个花名册,其中包含多个 Number,每个 Number 可以有多个 Student。 (表现 > 人数 > 学生)
  • 为什么要跨多个表存储学生?如果有一些差异,比如学年或班级,可以很容易地用新的列或属性来表示。
  • @Nyssa - 我在上面添加了更多代码,希望它更清楚。表格是根据 gridview 的行获取的
  • 你说的是,你有多个具有完全相同结构的表。这是非常不寻常的。将同一个学生放在同一个数据库的多个表中不是标准化数据。

标签: c# datatable duplicates dataset


【解决方案1】:

你可以使用(不同的方法)

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

【讨论】:

    【解决方案2】:

    你的问题有点缺乏细节,但如果我们按照一组假设工作:

    • 您有一个包含 N 个表的数据集
    • 所有表都有一个 int 类型的 StudentID 列
    • 您想检测已重复的特定整数

    以下代码将为您提供一个引用所有重复行的列表:

    HashBag<int> idx = new HashBag<int>();
    List<DataRow> dupRows = new List<DataRow>();
    
    foreach(DataTable dt in dataset.Tables)
    {
      foreach(DataRow dr in dt.Rows)
      {
        int sid = (int)dr["StudentID"];
        if(idx.Contains(sid))
          dupRows.Add(dr);
        else
          idx.Add(sid);
      }
    }
    

    DataRows 具有指向它们所在表的链接,因此如果您需要引用特定行所在的数据表,请调用例如dupRows[0].Table

    如果您想要第一行以及它的所有重复项,请考虑使用字典:

    Dictionary<int, DataRow> idx = new Dictionary<int, DataRow>();
    List<DataRow> dupRows = new List<DataRow>();
    
    foreach(DataTable dt in dataset.Tables)
    {
      foreach(DataRow dr in dt.Rows)
      {
        int sid = (int)dr["StudentID"];
        if(idx.Contains(sid))
          dupRows.Add(dr);
        else
          idx[sid] = dr;
      }
    }
    

    现在字典包含第一个遇到的行,列表包含它的所有重复项

    【讨论】:

    • 非常感谢!你的假设是正确的,我应该在我的问题中更清楚地说明这一点。我会实现这个。
    猜你喜欢
    • 2019-12-08
    • 1970-01-01
    • 2015-03-05
    • 1970-01-01
    • 1970-01-01
    • 2021-12-13
    • 1970-01-01
    • 2015-04-07
    • 1970-01-01
    相关资源
    最近更新 更多