我有一个数据表,其中可能存在几乎相同的行,但一列“ FileID”中的值除外。可以不同的列包含Int32数据,当行重复时,我只想保留具有该列最大值的行。如果行不是重复的,我想保留单行。
var Test = dt.AsEnumerable()
.GroupBy(r => new
{
Tool = r.Field<string>("Tool"),
Plate = r.Field<string>("Plate"),
Lot = r.Field<string>("Lot"),
Time1 = r.Field<DateTime>("Time1"),
Tool2 = r.Field<string>("Tool2"),
Time2 = r.Field<DateTime>("Time2"),
Recipe = r.Field<string>("Recipe"),
Row = r.Field<Int16>("Row")
}).OrderBy(t => t.Max(r => r.Field<Int32>("FileID")));
这似乎正确地过滤了行,但是我丢失了FileID列。我想将此查询的结果放回具有最大FileID的数据表中,以便可以在表单的datagridview中使用它。这怎么可能?
答案 0 :(得分:1)
按适当的列分组后,您只需从每个组中选择最大为FileID
的行,然后即可使用CopyToDataTable
扩展名:
var ans = dt.AsEnumerable()
.GroupBy(r => new {
Tool = r.Field<string>("Tool"),
Plate = r.Field<string>("Plate"),
Lot = r.Field<string>("Lot"),
Time1 = r.Field<DateTime>("Time1"),
Tool2 = r.Field<string>("Tool2"),
Time2 = r.Field<DateTime>("Time2"),
Recipe = r.Field<string>("Recipe"),
Row = r.Field<Int16>("Row")
})
.Select(rg => rg.OrderByDescending(r => r.Field<Int32>("FileID")).First())
.CopyToDataTable();
注意:假设您使用的是LINQ to Objects,OrderBy
/ First
并不是查找具有最大FileID
的行的最有效方法。您可能没有足够的数据要紧,但是可以使用扩展方法MaxBy
,该方法对数据进行一次遍历并找到适当的行:
public static T MaxBy<T, TKey>(this IEnumerable<T> src, Func<T, TKey> keySelector) => src.Aggregate((a, b) => Comparer<TKey>.Default.Compare(keySelector(a), keySelector(b)) > 0 ? a : b);
var ans = dt.AsEnumerable()
.GroupBy(r => new {
Tool = r.Field<string>("Tool"),
Plate = r.Field<string>("Plate"),
Lot = r.Field<string>("Lot"),
Time1 = r.Field<DateTime>("Time1"),
Tool2 = r.Field<string>("Tool2"),
Time2 = r.Field<DateTime>("Time2"),
Recipe = r.Field<string>("Recipe"),
Row = r.Field<Int16>("Row")
})
.Select(rg => rg.MaxBy(r => r.Field<Int32>("FileID")))
.CopyToDataTable();