Реализация фильтров для отображения таблицы SQL в представлении в ASP.NET MVC (C#) и LINQ-to-SQL?

StackOverflow https://stackoverflow.com/questions/491563

Вопрос

Продолжение от этот вопрос, я изменил свой контроллер и маршрутизацию, так что теперь значение сортировки назначается с помощью ?sort=, однако я также хочу реализовать для пользователей возможность фильтровать таблицу на основе выбранного набора значений:

Техник:Тех1, Тех2, Тех3 и т. д.Категория :Категория1, Категория2, Категория3 и т. д.Приоритет:Приоритет1, Приоритет2, Приоритет3 и т. д.

На данный момент я использую только одну таблицу, поэтому самый простой способ получить список доступных категорий для фильтрации — это выбрать отдельные значения категории из таблицы.Все они вводятся через HTML, поэтому я могу контролировать, что вводится.Я пока не хочу разбивать их все на разные таблицы, сейчас я пытаюсь сделать как можно больше с одной таблицей, но если это сценарий, который нарушает модель одной таблицы, тогда хорошо, я могу регулировать.

Чтобы прояснить вариант использования, вероятно, лучше показать быстрый снимок экрана рассматриваемого представления:

http://images.robburke.ie/stackoverflow/491563.png
Нажмите, чтобы просмотреть в полном размере.

Я хочу реализовать систему, в которой пользователь мог бы, например, фильтровать «Приоритет», чтобы отображать только те проблемы, приоритет которых был «Расследование».

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

Может ли кто-нибудь порекомендовать хороший способ сделать это?

Это было полезно?

Решение

Уровень сервера

Начнем с псевдокода.

public ActionResult Open(string sort, string technician, 
    string category, string priority)
{
    // generate query
    // filter stuff
    // order/sort stuff
}

Здесь важно правильно определить порядок операций.Некоторые поставщики IQueryable (Я смотрю на тебя, Entity Framework) будет молча игнорировать порядок, если он предшествует фильтрации.Итак, начните с создания неупорядоченного, нефильтрованного запроса, как и в случае с вашим последним вопросом, затем добавьте фильтрацию и, наконец, добавьте порядок.

Обратите внимание, что я добавил аргумент к вашему действию для каждого возможного варианта фильтра.Это один из способов сделать это.Другой способ сделать это - разрешить фильтрацию практически всего, путем итерации параметров строки запроса (внутри запроса), рассматривая все, что не называется «сортировкой», как потенциальный фильтр.Вам следует выбрать то, что лучше всего подходит для вашего приложения.

Теперь, как на самом деле реализовать фильтрацию?То, что показал Марк, — это один из способов.Это работает очень хорошо, если вы собираетесь фильтровать только определенные случаи.Очевидно, я бы поместил это во вспомогательный метод, а не в само действие.Скорее всего, вам придется повторно использовать этот помощник и другие действия.Однако если вы намерены предложить фильтрацию по большему количеству строк, чем вам нужно, в одном методе, другим способом будет использование библиотеки Microsoft Dynamic LINQ, которую вы можете получить из CodePlex.Это позволяет вам создавать LINQ, используя строки вместо лямбда-выражений.

Уровень браузера

Теперь, когда ваше приложение может справиться с этим, вам нужен метод создания ссылки, который выглядит следующим образом:

http://example.com/Issue/Open?sort=ID&priority=Investigative

Например, если у вас есть меню параметров фильтра, каждый пункт меню будет соответствовать ссылке с различными параметрами строки запроса.

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

Итак, общий подход, который мы используем при этом, заключается в следующем: для каждого элемента «меню фильтрации» (или любой другой ссылки на ваше здание):

  1. Создайте RouteValueDictionary параметров строки запроса.
  2. Добавьте в словарь все параметры строки запроса, переданные в текущее представление.
  3. Добавьте дополнительный параметр строки запроса для текущего пункта меню.
  4. Создайте конечный URL-адрес, используя Html.RouteLink и созданный нами словарь.

Другие советы

Я не совсем понимаю вариант использования, но вы можете легко добавить фильтры через IQueryable<T>:

var query = /* your primary query */

if(!string.IsNullOrEmpty(name)) {
    query = query.Where(row => row.Name == name);
}

if(activeOnly) {
    query = query.Where(row => row.IsActive);
}

и т. д.

Вы можете делать более сложные вещи, создавая Expression вручную, но вышеописанное имеет то преимущество, что его легко отлаживать и проверять компилятором (компилятор обеспечит наличие подходящего IsActive имущество и т. д.)

Лицензировано под: CC-BY-SA с атрибуция
Не связан с StackOverflow
scroll top