代码之家  ›  专栏  ›  技术社区  ›  Rob Burke

在ASP.NET MVC(C)和LINQ to SQL的视图上实现SQL表显示的筛选器?

  •  0
  • Rob Burke  · 技术社区  · 16 年前

    跟进 this question ,我已经更改了控制器和路由,以便现在排序值由分配?sort=但是,我还希望实现用户根据一组选定的值筛选表的功能:

    技术员:tech1、tech2、tech3等。 类别:类别1、类别2、类别3等。 优先级:优先级1、优先级2、优先级3等。

    目前我只使用一个表,因此获取要筛选的可用类别列表的最简单方法是从表中选择类别的不同值。它们都是通过HTML S输入的,所以我可以控制输入的内容。我现在还不想把它们都拆分成不同的表,我正在尽可能多地使用一个表,但是如果这是一个破坏了单表模型的场景,那么我可以调整。

    为了澄清用例,最好显示有关视图的快速屏幕截图:

    http://images.robburke.ie/stackoverflow/491563.png
    Click to view full-size.

    我想实现一个系统,在这个系统中,用户可以过滤“优先级”,只显示优先级为“调查性”的问题。

    我正在寻找如何在前端和后端实现这一点的建议。我试着找到一个网站,它可以做一些类似于数据表的事情,但我想不出我头脑中的一个顶端,尽管我确信这是一个已经实现了100次的功能!

    有人能推荐一个好的方法吗?

    2 回复  |  直到 16 年前
        1
  •  1
  •   Craig Stuntz    16 年前

    服务器层

    让我们从一些伪代码开始。

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

    重要的是要把操作顺序弄清楚,在这里。某些IQueryable提供程序( 我在看你,实体框架 )如果排序在筛选之前,则将静默地忽略排序。因此,首先生成一个无序的、未过滤的查询,就像上一个问题一样,然后附加筛选,最后附加排序。

    请注意,我已经为您的每个可能的过滤器案例的操作添加了一个参数。这是一种方法。另一种方法是,通过迭代查询字符串参数(在请求内部),将任何未被称为“排序”的内容视为一个潜在的筛选器,允许对任何内容进行筛选。您应该选择最适合您的应用程序的内容。

    现在,您如何实际实现过滤呢?马克展示的是一种方式。如果你只想过滤某些情况,那就非常有效。显然,我将把它放在一个辅助方法中,而不是放在操作本身中。很有可能您需要重用这个助手和其他操作。但是,如果您打算在一个方法中对更多的行提供筛选,另一种方法是使用Microsoft动态LINQ库,您可以从codeplex中获得该库。这允许您构建一个Linq.where,使用字符串而不是lambda表达式。

    浏览器层

    既然您的应用程序可以处理这个问题,那么您需要一种创建链接的方法,如下所示:

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

    例如,如果您有一个过滤器选项菜单,那么每个菜单项将对应一个具有不同查询字符串参数的链接。

    这有点棘手,因为在添加新的查询字符串时,您可能希望保留现有的查询字符串参数。例如,如果用户已按ID对打开的问题进行了排序,并选择只筛选调查性优先级问题,那么您仍然希望保留排序。因此,菜单中的所有链接都需要包括当前显示页面的查询字符串参数以及菜单项本身的查询字符串参数。

    因此,我们在执行此操作时采用的一般方法是,对于“过滤菜单”(或任何链接您的建筑的项目)中的每个项目:

    1. 创建查询字符串参数的RouteValueDictionary
    2. 将传递给当前视图的所有查询字符串参数添加到字典中。
    3. 为当前菜单项添加其他查询字符串参数。
    4. 使用html.routelink和我们构建的字典生成最终的URL。
        2
  •  0
  •   Marc Gravell    16 年前

    我不完全理解用例-但是您可以通过 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 财产等)