代码之家  ›  专栏  ›  技术社区  ›  Solomon

如何构造控制器对多个条件进行排序ASP.NET MVC

  •  2
  • Solomon  · 技术社区  · 16 年前

    设置控制器以按多个(可能为空)条件排序的最佳方法是什么?比如说,我在建一个卖汽车的网站。我的CarController有一个函数index(),它返回一个汽车列表到视图,并且每辆汽车的详细信息都用一个局部视图呈现。

    构造这个的最佳方法是什么?特别是如果有很多标准:汽车类型(又称SUV)、汽车品牌、汽车型号、汽车年份、汽车价格、汽车颜色、bool isnew,或者如果我想按最接近我的方式排序等等……我用NHibernate做我的ORM。我是否应该有大量可能的nhibernate查询,并根据控制器中的if/then来确定要选择哪一个?或者有更简单的方法。

    非常感谢你的帮助。

    2 回复  |  直到 16 年前
        1
  •  1
  •   LukLed    16 年前

    我的系统中有任务,并创建了用于搜索的特殊类:

    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);
    }
    

    这是实体框架,但也可以通过向iquery添加where子句在nhibernate中轻松完成。

    要搜索,我在控制器中有一个方法:

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

    有一个用于过滤的类是很好的,因为它可以序列化并保存到数据库中以备将来使用。这样用户就可以重用过滤器参数。

    你会有:

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

    如果列表为空,则不应用筛选器。

        2
  •  0
  •   richeym    16 年前

    如果您有很多条件,我发现最好是封装在一个类中,而不是传递很多操作参数。例如,我目前正在处理的项目有一个具有以下签名的操作:

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

    存储库方法只是简单地逐步通过建立iQueryable的标准。此特定项目使用LINQ to SQL,但相同的主体可以使用NHibernates标准API(或LINQ to NH)应用。