Как структурировать контроллер для сортировки нескольких критериев asp.net mvc - PullRequest
2 голосов
/ 09 марта 2010

Каков наилучший способ настроить контроллер для сортировки по многим (возможно, нулевым) критериям? Скажем, например, я строил сайт, который продавал автомобили. Мой CarController имеет функцию Index (), которая возвращает в список IList автомобилей, а детали каждого автомобиля отображаются с частичным представлением.

Какой лучший способ структурировать это? Особенно, если существует множество критериев: тип автомобиля (он же внедорожник), марка автомобиля, модель автомобиля, год выпуска автомобиля, цена автомобиля, цвет автомобиля, bool IsNew, или если я хочу отсортировать по ближайшему мне и т. Д ... Я использую NHibernate в качестве моего ORM. Должен ли я иметь только тонну возможных запросов NHibernate и выяснить, какой из них выбрать на основе if / then в контроллере? Или есть более простой способ.

Большое спасибо за помощь.

Ответы [ 2 ]

1 голос
/ 09 марта 2010

У меня есть задачи в моей системе и я создал специальный класс для поиска:

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, добавив предложения where в IQuery.

Для поиска у меня есть метод в контроллере:

[HttpPost]
public ActionResult TaskSearch([Bind(Prefix = "Search")]TaskSearchCriteria criteria)

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

Вы бы получили:

public class CarSearchCriteria
{
    List<int> ListOfCarTypesIds;
    List<int> ListOfCarBrandIds;
    bool IsNew;
    //and more
}

Если список пуст, вы не применяете фильтр.

0 голосов
/ 09 марта 2010

Если у вас много критериев, я считаю, что лучше инкапсулировать в классе, чем передавать множество параметров действий. Например, проект, над которым я сейчас работаю, имеет действие со следующей подписью:

public claass JobsController : Controller 
{
    public IList<JobDto> Index(JobSearchCriteria criteria)
    { 
        IList<JobDto> jobs = _jobs.Find(criteria);
        //... 
    }
}

Метод репозитория просто проходит по критериям, создавая IQueryable по мере его продвижения. Этот конкретный проект использует Linq To Sql, но тот же принцип может применяться с помощью API критериев NHibernates (или Linq to NH).

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