Выберите строки из DataSet с помощью LINQ, где список RowsID находится в Списке <T>

Я сказал бы, что второй лучше, потому что он перестал работать быстрее, когда завершение " отсутствует. Первый отследит в обратном порядке по строке, потенциально дорогой операции. Альтернатива regexp при использовании жемчуга 5.10, была бы /"[^"]++"/. Это передает то же значение, как версия 1 делает, но с такой скоростью, как версия два.

6
задан GTuritto 12 August 2009 в 22:04
поделиться

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);
}
7
ответ дан 10 December 2019 в 02:51
поделиться

Я обычно использую методы расширения, когда мне нужно рассматривать объект, предшествующий LINQ, как объект, готовый к LINQ. Например, вы хотите запросить DataRowCollection (свойство DataTable.Rows), которое вы, вероятно, не используете ни для чего, кроме списка DataRows. Я бы сделал метод расширения, который выполняет это преобразование за вас (DataRowCollection в List ). Я также обычно использую метод расширения для безопасного получения значений, когда мне не нужно генерировать исключение, если по какой-либо причине для столбца указано недопустимое имя ключа. Затем вы можете создать метод расширения, который принимает список целых чисел в качестве идентификаторов и имя поля, содержащее идентификатор для возврата того, что вы хотите. Когда все сказано и сделано, это делается с помощью одной строчки кода. Вот класс со всеми вашими методами расширения.

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

Затем, кроме настройки ваших переменных (что вам не нужно делать ... они у вас уже есть), настоящая работа выполняется с помощью одной строки кода (EDIT: один вызов метода):

        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
ответ дан 10 December 2019 в 02:51
поделиться
Другие вопросы по тегам:

Похожие вопросы: