如何在DataTable中只获取具有相同id的最新条目

本文关键字:id 最新 DataTable 获取 | 更新日期: 2023-09-27 17:58:08

我有以下内容:

DataTable table = new DataTable();
table.Columns.Add("id", typeof(string));
table.Columns.Add("date", typeof(DateTime));
DateTime date1 = new DateTime(2008, 3, 1, 7, 0, 0);
DateTime date2 = new DateTime(2007, 3, 1, 7, 0, 0);
DateTime date3 = new DateTime(2006, 3, 1, 7, 0, 0);
table.Rows.Add("123", date1);
table.Rows.Add("123", date2);
table.Rows.Add("ABC", date3);

我想运行一个操作,删除所有与另一行id相同的行,只保留最新日期的行。

在这个开头的小例子中,我有:

123 2008...
123 2007...
ABC 2006...

行动之后应该是:

123 2008...
ABC 2006...

我怎么能意识到这一点?

(这只是一个小例子,我的实际数据要大得多)

如何在DataTable中只获取具有相同id的最新条目

假设您不能直接过滤数据源中的数据(=调整SQL查询),则可以使用以下代码删除行:

var multiDates = from dr in table.AsEnumerable()
                 group dr by dr.Field<string>("id") into grp
                 where grp.Count() > 1
                 select grp.OrderByDescending(gr => gr.Field<DateTime>("date"));
var toDelete = multiDates
    .SelectMany(rows => rows.Skip(1))
    .ToArray();
foreach (var row in toDelete)
    row.Delete();
table.AcceptChanges();

如果您希望在插入所有数据后进行检查,可以使用DataView对DataTable数据进行排序,枚举所有行,检查重复项并将其删除。。

DataView dv = new DataView(DATA_TABLE, "", "ID, Date DESC", DataViewRowState.None);
for (int i = 1; i < dv.Count; i++)
{
    if (dv[i - 1].Row["ID"] == dv[i].Row["ID"])
    {
       dv[i].Delete();
       i--;
    }
 }

如果您可以在插入时进行检查,请使用某种方法,例如EndEdit_Event来检查重复的ID

您甚至可以考虑使用某种dataSource(ArrayList、List、DataSet aso),并使用约束或一些businessLogic检查。

这里有一个替代

 var rowsToDelete = 
              (from outer in table.AsEnumerable()
              where !(from inner in table.AsEnumerable()
                    group inner by inner.Field<string>("id") into grp
                    where grp.Key == outer.Field<string>("id") &&
                          grp.Max (g => g.Field<DateTime>("date")) == outer.Field<DateTime>("date")
                    select grp.Key).Any()
              select outer).ToList();
foreach (var row in rowsToDelete) 
   row.Delete();
table.AcceptChanges();

您可以使用linq查询不同的字段ID,如下面的

var MyQry=(from P5 in table.AsEnumerable() select P5["id"]).Distinct().ToList();
for (int O1 = 0; O1 < MyQry.Count; O1++)
{
     richTextBox1.Text = MyQry[O1].ToString();
}