6

我有一个清单。我想过滤表列表中的所有行,以查找列表中每个数据表中的所有行。

如果可能,比较需要在每一行的“ID”列上。

我试图用 Linq 解决这个问题,但被卡住了。这是我到目前为止所拥有的:

List<DataTable> dataTables = new List<DataTable>();

// fill up the list
List<DataRow> dataRows = 
    dataTables.SelectMany(dt => dt.Rows.Cast<DataRow>().AsEnumerable()).
    Aggregate((r1, r2) => r1.Intersect(r2));

有什么建议么?

4

2 回答 2

4

不是一个简单的问题。这是一个解决方案(对我来说似乎太复杂了,但它有效)。

  • 使用 Linq to DataSets 从每一行获取 Id 值
  • 交叉多个列表以找到所有公共值
  • 在具有匹配 id 之一的所有行中查找单个出现的行

要在 DataTable 上使用 Linq,请参阅这篇文章作为开始。

您可以像这样从一张表中获取 id

var ids = dt.AsEnumerable().Select (d => d.Field<int>("ID")).OfType<int>();

并从多个表

var setsOfIds = dataTables.Select (
    t => t.AsEnumerable().Select (x => x.Field<int>("ID")).OfType<int>());

要交叉多个列表,请尝试这篇文章。使用其中一种方法,您可以获得所有 id 的交集。

使用 Jon Skeet 的辅助方法

public static class MyExtensions
{
    public static List<T> IntersectAll<T>(this IEnumerable<IEnumerable<T>> lists)
    {
        HashSet<T> hashSet = new HashSet<T>(lists.First());
        foreach (var list in lists.Skip(1))
        {
            hashSet.IntersectWith(list);
        }
        return hashSet.ToList();
    }
}

我们可以写

var commonIds = setsOfIds.InsersectAll();

现在展平 DataTables 中的所有行并按公共 id 过滤:

var rows = dataTables.SelectMany (t => t.AsEnumerable()).Where(
    r => commonIds.Contains(r.Field<int>("ID")));

现在按 id 分组并获取每行的第一个实例:

var result = rows.GroupBy (r => r.Field<int>("ID")).Select (r => r.First ());
于 2012-05-24T14:49:04.200 回答
1

试试这个来找到两个列表之间的交集:

r1.Join(r2, r1 => r1.Id, r2 => r2.Id, (r1, r2) => r1);
于 2012-05-24T13:16:21.667 回答