DataView.RowFilter Vs DataTable.Select () vs DataTable.Rows.Find () - PullRequest
31 голосов
/ 14 мая 2010

С учетом кода ниже:

Dataview someView = new DataView(sometable)
someView.RowFilter = someFilter;

if(someView.count > 0) {  …. }

Довольно много статей, в которых говорится, что Datatable.Select () лучше, чем использование DataView, но они до VS2008.

Решено: Тайна плохой работы DataView с большими наборами записей
Массив DataRecord против DataView: существенное различие в производительности

Погуглив по этой теме, я нашел несколько статей / тем на форуме, в которых упоминается Datatable.Select () сам по себе довольно глючный (не уверен в этом) и не дает результатов в различных сценариях.

В этом ( Best Practices ADO.NET ) разделе о msdn предлагается, чтобы при наличии первичного ключа, определенного для таблицы данных, методы findrows () или find () использовались вместо Datatable. Выберите ().

В этой статье здесь (.NET 1.1) сравниваются все три подхода и еще пара. Но это для версии 1.1, поэтому не уверен, что они действительны до сих пор. В соответствии с этим DataRowCollection.Find () превосходит все подходы, а Datatable.Select () превосходит DataView.RowFilter.

Так что я совершенно запутался в том, что может быть лучшим подходом при поиске строк в таблице данных. Или не существует единственного хорошего способа сделать это, в зависимости от сценария существует несколько решений?

Ответы [ 2 ]

52 голосов
/ 19 мая 2010

Вы ищете «лучший подход к поиску строк в таблице данных», поэтому я сначала должен спросить: «лучший» для чего? Я думаю, что у любой техники есть сценарии, в которых она может подходить лучше, чем у других.

Во-первых, давайте посмотрим на DataView.RowFilter: DataView имеет некоторые преимущества в привязке данных. Он очень ориентирован на просмотр, поэтому имеет мощные функции сортировки, фильтрации или поиска, но создает некоторые накладные расходы и не оптимизирован для производительности. Я бы выбрал DataView.RowFilter для небольших наборов записей и / или где вы используете другие функции (например, прямую привязку данных к представлению).

Большинство фактов о DataView, которые вы можете прочитать в старых постах, по-прежнему применимы.

Во-вторых, вы должны предпочесть DataTable.Rows.Find, чем DataTable.Select, если вы хотите всего один удар. Зачем? DataTable.Rows.Find возвращает только одну строку. По сути, когда вы указываете первичный ключ, создается двоичное дерево. Это связано с некоторыми накладными расходами, но значительно ускоряет поиск.

DataTable.Select медленнее, но может оказаться очень полезным, если у вас несколько критериев и вам нет дела до проиндексированных или неиндексированных строк: он может найти практически все, но не оптимизирован для производительности. По сути, DataTable.Select должен пройти всю таблицу и сравнить каждую запись с критериями, которые вы передали.

Надеюсь, этот небольшой обзор окажется полезным.

Я бы посоветовал взглянуть на эту статью , она была полезной для меня по вопросам производительности. Этот пост содержит некоторые цитаты из него.

Немного ОБНОВЛЕНИЯ: Кстати, это может показаться немного за рамками вашего вопроса, но это почти всегда самое быстрое решение для фильтрации и поиска на серверной части. Если вы хотите простоты и имеете SQL Server в качестве бэкэнда и .NET3 + на клиенте, перейдите к LINQ-to-SQL. Поиск объектов Linq очень удобен и создает запросы, которые выполняются на стороне сервера. Хотя LINQ-to-Objects тоже очень удобная, но и более медленная техника. Если ты еще не знал ....

25 голосов
/ 21 мая 2010

Пост Томасаида хорошо подводит итог:

  • DataView.RowFilter для переплета.
  • DataTable.Rows.Find для поиска по первичному ключу только .
  • DataTable.Select - для поиска по нескольким столбцам, а также для указания заказа.

Избегайте создания многих DataView в цикле и использования их RowFilters для поиска записей. Это резко снизит производительность.

Я хотел бы добавить, что DataTable.Select может использовать индексы. Вы можете создать индекс для DataTable, создав DataView и указав порядок сортировки:

DataView dv = new DataView(dt);
dv.Sort = "Col1, Col2";

Затем, когда вы вызываете DataTable.Select(), он может использовать этот индекс при выполнении запроса. Мы использовали эту технику, чтобы серьезно повысить производительность в местах, где мы используем один и тот же запрос много, много раз. (Обратите внимание, что это было до того, как появился Linq.)

Хитрость в том, чтобы правильно определить порядок сортировки для оператора Select. Так что если ваш запрос "Col1 = 1 и Col2 = 4", то вам понадобится "Col1, Col2", как в примере выше.

Обратите внимание, что создание индекса может зависеть от фактических вызовов для создания DataView. Нам пришлось использовать конструктор new DataView(DataTable dt), а затем указать свойство Sort на отдельном шаге. Поведение может немного измениться в разных версиях .NET.

Добро пожаловать на сайт PullRequest, где вы можете задавать вопросы и получать ответы от других членов сообщества.
...