Warning: file_get_contents(/data/phpspider/zhask/data//catemap/2/csharp/288.json): failed to open stream: No such file or directory in /data/phpspider/zhask/libs/function.php on line 167

Warning: Invalid argument supplied for foreach() in /data/phpspider/zhask/libs/tag.function.php on line 1116

Notice: Undefined index: in /data/phpspider/zhask/libs/function.php on line 180

Warning: array_chunk() expects parameter 1 to be array, null given in /data/phpspider/zhask/libs/function.php on line 181
C#-从数据表中删除具有相同列值的行_C#_Linq_Datatable_Filtering - Fatal编程技术网

C#-从数据表中删除具有相同列值的行

C#-从数据表中删除具有相同列值的行,c#,linq,datatable,filtering,C#,Linq,Datatable,Filtering,我有一个数据表,看起来像这样: ID Name DateBirth ....................... 1 aa 1.1.11 2 bb 2.3.11 2 cc 1.2.12 3 cd 2.3.12 以下哪种方法是删除具有相同ID的行的最快方法(保留第一个匹配项,删除下一个匹配项): 我不想重复传递表中的行,因为行号很大。 如果可能的话,我想使用一些LinQ,但我想这将是一个很大的查询,我必

我有一个
数据表
,看起来像这样:

 ID   Name    DateBirth
.......................
 1     aa      1.1.11
 2     bb      2.3.11
 2     cc      1.2.12
 3     cd      2.3.12
以下哪种方法是删除具有相同ID的行的最快方法(保留第一个匹配项,删除下一个匹配项):

我不想重复传递表中的行,因为行号很大。 如果可能的话,我想使用一些LinQ,但我想这将是一个很大的查询,我必须使用比较器。

您可以试试这个

DataTable uniqueCols = dt.DefaultView.ToTable(true, "ID");

您可以使用LINQ to DataTable,根据列
ID
进行区分,您可以在此列上分组,然后首先选择:

var result=dt.AsEnumerable()
.GroupBy(r=>r.Field(“ID”))
.Select(g=>g.First())
.CopyToDataTable();

不一定是最有效的方法,但可能是最可读的方法:

table = table.AsEnumerable()
    .GroupBy(row => row.Field<int>("ID"))
    .Select(rowGroup => rowGroup.First())
    .CopyToDataTable();
  • 获取每个
    ID
  • 确定要保留的记录(不知道您的标准;我将按DoB排序,然后
    名称
    并保留第一条记录),然后选择其余的记录
  • 删除行
  • 接受更改

  • 有一种方法可以实现这一点, 您需要使用的所有库都使用它的功能
    DistinctBy

    代码:

    protected void Page_Load(object sender, EventArgs e)
    {
      var DistinctByIdColumn = getDT2().AsEnumerable()
                                       .DistinctBy(
                                       row => new { Id = row["Id"] });
      DataTable dtDistinctByIdColumn = DistinctByIdColumn.CopyToDataTable();
    }
    
    
    public DataTable getDT2()
    {
       DataTable dt = new DataTable();
       dt.Columns.Add("Id", typeof(string));
       dt.Columns.Add("Name", typeof(string));
       dt.Columns.Add("Dob", typeof(string));
       dt.Rows.Add("1", "aa","1.1.11");
       dt.Rows.Add("2", "bb","2.3.11");
       dt.Rows.Add("2", "cc","1.2.12");
       dt.Rows.Add("3", "cd","2.3.12");
       return dt;
    }
    
    输出:如您所料


    我正在解决同样的问题,发现它非常有趣,我想与大家分享我的发现

  • 如果要根据所有列区分行
  • 您在这里提到的列,只有那些列将在
    newDatatable
    中返回

  • 如果基于一列的distinct和列类型为int,那么我更喜欢
    LINQ
    query
  • DataTable newDatatable=dt.AsEnumerable()
    .GroupBy(dr=>dr.Field(“ID”))
    。选择(dg=>dg)。取(1)
    .CopyToDataTable();
    
  • 如果基于一列的distinct和列类型为string,则我更喜欢循环
  • List toExclude=new List();
    对于(int i=0;i
    第三个是我最喜欢的

    我可能回答了几个问题中没有提到的问题。这是出于好意而做的,也没有什么刺激


    希望能有帮助。

    你试过什么?只是身份证的问题吗?其他字段是不相关的?通常的方式。2个for,并验证每行的ID字段。如果重复,请将其删除。但这是基本的、低性能的。是的,其他字段是不相关的。只有ID很重要。如果
    distinct
    基于两列,该怎么办?没有一个(即,在上述情况下,
    id
    )。
    table = table.AsEnumerable()
        .GroupBy(row => row.Field<int>("ID"))
        .Select(rowGroup => rowGroup.First())
        .CopyToDataTable();
    
    table = table.AsEnumerable()
        .GroupBy(row => row.Field<int>("ID"))
        .Select(rowGroup => rowGroup
                              .OrderByDescending(r => r.Field<DateTime>("DateBirth"))
                              .First())
        .CopyToDataTable();
    
    var rowsToDelete = 
        (from row in dataTable.AsEnumerable()
        group row by row.ID into g
        where g.Count() > 1
    
    select g.OrderBy( dr => dr.Field<DateTime>( "DateBirth" ) ).ThenBy( dr => dr.Field<string>( "Name" ) ).Skip(1))
    
    .SelectMany( g => g );
    
    rowsToDelete.ForEach( dr => dr.Delete() );
    
    dataTable.AcceptChanges();
    
    protected void Page_Load(object sender, EventArgs e)
    {
      var DistinctByIdColumn = getDT2().AsEnumerable()
                                       .DistinctBy(
                                       row => new { Id = row["Id"] });
      DataTable dtDistinctByIdColumn = DistinctByIdColumn.CopyToDataTable();
    }
    
    
    public DataTable getDT2()
    {
       DataTable dt = new DataTable();
       dt.Columns.Add("Id", typeof(string));
       dt.Columns.Add("Name", typeof(string));
       dt.Columns.Add("Dob", typeof(string));
       dt.Rows.Add("1", "aa","1.1.11");
       dt.Rows.Add("2", "bb","2.3.11");
       dt.Rows.Add("2", "cc","1.2.12");
       dt.Rows.Add("3", "cd","2.3.12");
       return dt;
    }
    
    DataTable newDatatable = dt.DefaultView.ToTable(true, "ID", "Name", "DateBirth");
    
      DataTable newDatatable = dt.AsEnumerable()
                               .GroupBy(dr => dr.Field<int>("ID"))
                               .Select(dg => dg).Take(1)
                               .CopyToDataTable();
    
    List<string> toExclude = new List<string>();
    for (int i = 0; i < dt.Rows.Count; i++)
    {
        var idValue = (string)dt.Rows[i]["ID"];
        if (toExclude.Contains(idValue))
        {
            dt.Rows.Remove(dt.Rows[i]);
            i--;
        }
        toExclude.Add(glAccount);
    }