Как лучше всего настроить контроллер для сортировки по многим (возможно, нулевым) критериям? Скажем, например, я создавал сайт по продаже автомобилей. В My CarController есть функция Index (), которая возвращает список автомобилей в виде списка, и сведения о каждой машине отображаются с частичным представлением.
Как лучше всего это структурировать? Особенно, если критериев много: тип автомобиля (он же внедорожник), марка автомобиля, модель автомобиля, год автомобиля, цена автомобиля, цвет автомобиля, bool IsNew, или если я хочу отсортировать по ближайшему ко мне и т. Д. m, используя NHibernate в качестве ORM. Должен ли я иметь всего тонну возможных запросов NHibernate и выяснить, какой из них выбрать, основываясь на if / then в контроллере? Или есть способ попроще.
Большое спасибо за помощь.
2 ответа
У меня есть задачи в системе и я создал специальный класс для поиска:
public class TaskSearchCriteria
{
public List<int> Statuses { get; set; }
public List<int> Severities { get; set; }
public List<int> CreatedBy { get; set; }
public List<int> ClosedBy { get; set; }
public List<int> LastModificationBy { get; set; }
public DateTime? CreationDateFrom { get; set; }
public DateTime? CreationDateTo { get; set; }
public bool SearchInComments { get; set; }
public bool SearchInContent { get; set; }
public bool SearchInTitle { get; set; }
}
Один из методов этого класса применяет фильтры:
public IQueryable<Task> Filter(IQueryable<Task> tasks)
{
return
FilterDates(
FilterAssignedTo(
FilterGroups(
FilterOperationSystems(
FilterPlatforms(
FilterPriorities(
FilterSeverities(
FilterVersionsResolved(
FilterVersionsReported(
FilterTaskContent(
FilterStatuses(tasks)))))))))));
}
Это один из методов, используемых для фильтрации:
private IQueryable<Task> FilterSeverities(IQueryable<Task> tasks)
{
if (Severities.Contains(TaskSearchConsts.All) || (!Severities.Any()))
return tasks;
var expressions = new List<Expression>();
if (Severities.Contains(TaskSearchConsts.Active))
expressions.Add(_taskParameter.EqualExpression("Severity.IsActive", 1));
return tasks.WhereIn(_taskParameter, "Severity.ID", Severities, expressions);
}
Это Entity Framework, но это можно легко сделать и в nHibernate, добавив в IQuery предложения where.
Для поиска у меня есть метод в контроллере:
[HttpPost]
public ActionResult TaskSearch([Bind(Prefix = "Search")]TaskSearchCriteria criteria)
Наличие одного класса для фильтрации - это хорошо, потому что его можно сериализовать и сохранить в базе данных для использования в будущем. Таким образом, пользователь может повторно использовать параметры фильтра.
Вам придется:
public class CarSearchCriteria
{
List<int> ListOfCarTypesIds;
List<int> ListOfCarBrandIds;
bool IsNew;
//and more
}
Если список пуст, вы не применяете фильтр.
Если у вас много критериев, я считаю, что лучше инкапсулировать в класс, а не передавать множество параметров действия. Например, у проекта, над которым я сейчас работаю, есть действие со следующей подписью:
public claass JobsController : Controller
{
public IList<JobDto> Index(JobSearchCriteria criteria)
{
IList<JobDto> jobs = _jobs.Find(criteria);
//...
}
}
Метод репозитория просто проходит через критерии построения IQueryable по мере его продвижения. Этот конкретный проект использует Linq To Sql, но тот же принцип может применяться с использованием NHibernates Criteria API (или Linq to NH).
Похожие вопросы
Связанные вопросы
Новые вопросы
c#
C # (произносится как «резкий») - это высокоуровневый, статически типизированный язык программирования с несколькими парадигмами, разработанный Microsoft. Код C # обычно нацелен на семейство инструментов и сред выполнения Microsoft .NET, включая, среди прочего, .NET Framework, .NET Core и Xamarin. Используйте этот тег для вопросов о коде, написанном на C # или в формальной спецификации C #.