Подтвердить что ты не робот

DataView.RowFilter Vs DataTable.Select() vs DataTable.Rows.Find()

Учитывая следующий код:

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

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

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

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

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

На этом (Best Practices ADO.NET) тема на msdn предлагается, что если есть первичный ключ, определенный на datatable, ) или find() следует использовать insted of Datatable.Select().

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

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

4b9b3361

Ответ 1

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

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

Все данные о DataView, которые вы можете прочитать в старых сообщениях, по-прежнему применяются.

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

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

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

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

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

Ответ 2

Сообщение Thomashaid прекрасно подводит итог:

  • 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.