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