使用 LINQ 从数据集中选择行,其中 RowsID 的列表位于 List<T>

Posted

技术标签:

【中文标题】使用 LINQ 从数据集中选择行,其中 RowsID 的列表位于 List<T>【英文标题】:Select Rows from a DataSet using LINQ, where the list of RowsID's are in a List<T> 【发布时间】:2010-11-19 03:11:12 【问题描述】:

首先我必须说,我是使用 LINQ 的新手。实际上我以前从未使用过,但我有一个任务需要过滤 DataTable,使用来自列表的值。 所以我想知道在 LINQ 中是否可以使用列表中的值作为过滤器值来查询数据表。有人可以给我一些提示

谢谢。

【问题讨论】:

【参考方案1】:

当我需要将 pre-LINQ 对象视为 LINQ 就绪对象时,我通常会给自己扩展方法。例如,您要查询一个 DataRowCollection(DataTable.Rows 属性),您可能只将其用于 DataRows 列表。我会做一个扩展方法来为你做这个转换(DataRowCollection 到List&lt;DataRow&gt;)。如果由于某种原因为列提供了无效的键名,我通常也使用扩展方法来安全地获取值。然后,您可以创建一个扩展方法,该方法将整数列表作为 id 和包含 id 的字段名称以返回您想要的内容。当一切都说完了,这就是用一行代码完成的。这是包含所有扩展方法的类。

using System;
using System.Collections.Generic;
using System.Linq;
using System.Text;
using System.Data;

namespace ConsoleApplication11

    public static class SystemDataHelpers
    
        public static List<DataRow> RowList(this DataTable table)
        
            List<DataRow> list = new List<DataRow>();
            foreach (DataRow row in table.Rows)
                list.Add(row);
            return list;
        

        public static object GetItem(this DataRow row, string field)
        
            if (!row.Table.Columns.Contains(field))
                return null;
            return row[field];
        

        public static List<DataRow> GetRows(this DataTable table, List<int> ids, string fieldName)
        
            Func<DataRow, bool> filter = row => ids.Contains((int)row.GetItem(fieldName));
            return table.RowList().Where(filter).ToList();
        
    

然后,除了设置变量(您不需要这样做......您已经拥有它们)之外,真正的工作是通过一行代码完成的(编辑:单个方法调用):

        DataTable table = new DataTable();
        List<int> rowIds = new List<int>  1, 2, 3, 4 ;
        string idFieldName = "row_id";

        List<DataRow> selected = table.GetRows(rowIds, idFieldName);

【讨论】:

【参考方案2】:

执行此操作的最佳方法取决于您打算如何处理过滤后的结果。您是否需要将结果作为 DataTable 返回以进行进一步操作,或者您是否要对结果进行数据绑定?

以下面的示例为例,它返回匹配 DataRows 的(可绑定的)枚举器

//create sample table with sample rows
DataTable table = new DataTable();

table.Columns.Add("id", typeof(int));

for (int i = 1; i < 11; i++)

    DataRow row = table.NewRow();
    row[0] = i;
    table.Rows.Add(row);


//filter the table by id (in a list)
List<int> rowIds = new List<int>  1, 3, 6 ;

IEnumerable<DataRow> matchingRows = from DataRow row in table.Rows
                   where rowIds.Contains((int)row[0])
                   select row;

如果您需要 DataTable,您可以将行导入另一个表:

DataTable filteredTable = table.Clone();

foreach (DataRow filteredRow in matchingRows)

    filteredTable.ImportRow(filteredRow);

【讨论】:

转换为数据表的一种方法是使用 .CopyToDataTable(),在这种情况下,请确保在执行 matchingRows.CopyToDataTable() 之前检查 matchingRows.Any() 是否返回 true。这需要 System.Data.DataTableExtensions

以上是关于使用 LINQ 从数据集中选择行,其中 RowsID 的列表位于 List<T>的主要内容,如果未能解决你的问题,请参考以下文章

Linq 从视图中选择行?

LINQ2SQL 根据大 where 选择行

Panda .loc 或 .iloc 从数据集中选择列

从数据集中删除特定行

如何从Matlab中的数据集中选择随机样本[重复]

LINQ语句中的.AsEnumerable() 和 .AsQueryable()的区别