Я сказал бы, что второй лучше, потому что он перестал работать быстрее, когда завершение "
отсутствует. Первый отследит в обратном порядке по строке, потенциально дорогой операции. Альтернатива regexp при использовании жемчуга 5.10, была бы /"[^"]++"/
. Это передает то же значение, как версия 1 делает, но с такой скоростью, как версия два.
Лучший способ сделать это зависит от того, что вы планируете делать с отфильтрованными результатами. Вам нужны результаты в виде 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);
}
Я обычно использую методы расширения, когда мне нужно рассматривать объект, предшествующий 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);