Задача: отфильтровать данные, загруженные из базы в DataTable (DataSet) и DataGridView без повторного обращения к БД. В C# и WinForms для этого можно использовать свойство RowFilter классов BindingSource.Filter и DataView.RowFilter . На самом деле BindingSource просто передает условие фильтрации в DataView или DataTable (в последнем случае условия от разных BindingSource будут перезаписываться), так что первично свойство RowFilter, в которое пишется текстовое условие с очень напоминающим Sql синтаксисом.
Синтаксис RowFilter совпадает с синтаксисом свойства DataColumn.Expression, документацию к которому и надо использовать недоумевающему программисту. Тем не менее в работе этого свойства хватает подводных камней и неочевидных моментов:
1. Условие от и до, ключевое слово BETWEEN - банально не работает. Вместо него надо использовать комбинацию более простых выражений, например
someDataView.RowFilter = "ID >= 10 AND ID <= 60"
2. Даты. Преобразованные в строку значения datetime надо оборачивать не в кавычки, а в знак решетки #
someDataView.RowFilter = " SOME_DATE >= #" + MinDate + "# AND SOME_DATE <= #" + MaxDate + "#";
3. Региональные настройки даты не учитываются. Для использования в RowFilter дату надо самостоятельно преобразовать к формату месяц-день-год.
_minDate = Convert.ToDateTime(value).ToString("MM.dd.yyyy");
Если такие фильтры формируются часто, можно сделать функцию
public static string CreateDateRowFilterPart(string minDate, string maxDate, string columnName) { string dateFilterPart = ""; // преобразуем даты в специфичный для RowFilter формат string filterDateMin = ""; string filterDateMax = ""; if (minDate != "") { filterDateMin = Convert.ToDateTime(minDate).ToString("MM.dd.yyyy"); } if (maxDate != "") { filterDateMax = Convert.ToDateTime(maxDate).ToString("MM.dd.yyyy"); } // формируем фильтр с учетом возможного отсутствия одной из дат if (filterDateMin != "" && filterDateMax == "") { dateFilterPart = "( " + columnName + " >= #" + filterDateMin + "# )"; } else if (filterDateMin == "" && filterDateMax != "") { dateFilterPart = "( " + columnName + " <= #" + filterDateMax + "# )"; } else if (filterDateMin != "" && filterDateMax != "") { dateFilterPart = "(" + columnName + " >= #" + filterDateMin + "#" + " AND " + columnName + " <= #" + filterDateMax + "# )"; } return dateFilterPart; }