asp.net core 排序过滤分页组件:sieve(1)

使用asp.net core开发时避免不了要用一个合适的分页组件来让前端获取分页数据。github上面有一个开源的分页组件在这方面很适合我的使用,于是我把他的文档翻译一下,随后会分析它里面的源码。这是第一篇,介绍它如何使用。

Sieve

Sieves是一个.net core下面的简单、干净并且可扩展的框架,它对外暴露了排序,过滤和分页的功能。

ASP.NET Core下的使用方式

在本例中,考虑一个带有Post实体的应用程序。在获取所有可用的帖子时,我们将使用Sieve添加排序、过滤和分页功能。

1. 添加必要的服务

在StartUp.cs文件中编辑ConfigureService方法,将SieveProcessor服务注入进去:

services.AddScoped<SieveProcessor>();

2. 然后告诉Sieve你要让哪几个属性可以进行排序或过滤

Sieve只会对标记有Sieve Attribute的属性(例如:[Sieve(Cansort=true,CanFilter=true)])进行排序或者过滤,所以,在我们的Post的例子中:

public int Id { get; set; }

[Sieve(CanFilter = true, CanSort = true)]
public string Title { get; set; }

[Sieve(CanFilter = true, CanSort = true)]
public int LikeCount { get; set; }

[Sieve(CanFilter = true, CanSort = true)]
public int CommentCount { get; set; }

[Sieve(CanFilter = true, CanSort = true, Name = "created")]
public DateTimeOffset DateCreated { get; set; } = DateTimeOffset.UtcNow;

Name参数可以为客户端提供一个不一样的名字

NOTE:你可以使用Fluent API实现一样的功能,就像EF Core中的Fluent Api(IEntityTypeConfiguration)一样的道理和用法。

3.在Controller中使用SieveModel来获取排序、过滤以及分页查询参数

在下面这个Action中处理返回的Post,使用SieveModel来获取排序过滤以及分页查询参数。同时,将SieveProcessor注入到你的Controller中,只要使用它的Apply<TEntity>方法就可以了:

[HttpGet]
public JsonResult GetPosts(SieveModel sieveModel)
{
    var result = _dbContext.Posts.AsNoTracking(); // Makes read-only queries faster
    result = _sieveProcessor.Apply(sieveModel, result); // Returns `result` after applying the sort/filter/page query in `SieveModel` to it
    return Json(result.ToList());
}

你也可以通过应用这个方法中的可选参数来显式的指定你的意图,比如你只想要过滤或者配许,或者分页。具体查看它的Api吧。

4.发送一个请求

GET /GetPosts

?sorts=     LikeCount,CommentCount,-created         // sort by likes, then comments, then descendingly by date created
&filters=   LikeCount>10, [email protected]=awesome title,     // filter to posts with more than 10 likes, and a title that contains the phrase "awesome title"
&page=      1                                       // get the first page...
&pageSize=  10                                      // ...which contains 10 posts

添加自定义的排序/过滤方法

如果你想要添加自定义的排序和过滤方法,注入ISieveCustomSortMethodsISieveCustomFilterMethods这两个接口的实现就可以了,Sieve会查询到你注入的这两个接口并应用他们。

举例来说:

services.AddScoped<ISieveCustomSortMethods, SieveCustomSortMethods>();
services.AddScoped<ISieveCustomFilterMethods, SieveCustomFilterMethods>();

SieveCustomSortMethodsOfPosts是下面这样的:

public class SieveCustomSortMethods : ISieveCustomSortMethods
{
    public IQueryable<Post> Popularity(IQueryable<Post> source, bool useThenBy, bool desc) // The method is given an indicator of weather to use ThenBy(), and if the query is descending
    {
        var result = useThenBy ?
            ((IOrderedQueryable<Post>)source).ThenBy(p => p.LikeCount) : // ThenBy only works on IOrderedQueryable<TEntity>
            source.OrderBy(p => p.LikeCount)
            .ThenBy(p => p.CommentCount)
            .ThenBy(p => p.DateCreated);

        return result; // Must return modified IQueryable<TEntity>
    }
}

SieveCustomFilterMethods

public class SieveCustomFilterMethods : ISieveCustomFilterMethods
{
    public IQueryable<Post> IsNew(IQueryable<Post> source, string op, string[] values) // The method is given the {Operator} & {Value}
    {
        var result = source.Where(p => p.LikeCount < 100 &&
                                        p.CommentCount < 5);

        return result; // Must return modified IQueryable<TEntity>
    }
}

配置Sieve

使用ASP.NET Core options pattern这种方式来配置SieveOption,告诉Sieve从哪里找到配置。比如:

services.Configure<SieveOptions>(Configuration.GetSection("Sieve"));

你可以在Json文件中添加配置:

{
    "Sieve": {
        "CaseSensitive": "boolean: should property names be case-sensitive? Defaults to false",
        "DefaultPageSize": "int number: optional number to fallback to when no page argument is given. Set <=0 to disable paging if no pageSize is specified (default).",
        "MaxPageSize": "int number: maximum allowed page size. Set <=0 to make infinite (default)",
        "ThrowExceptions": "boolean: should Sieve throw exceptions instead of silently failing? Defaults to false"
    }
}

发送一个请求

上面那些步骤你都做了的话,你可以发送一个GET请求,请求中携带排序、过滤和分页查询参数,下面一个例子:
GET /GetPosts

?sorts=     LikeCount,CommentCount,-created         // sort by likes, then comments, then descendingly by date created
&filters=   LikeCount>10, [email protected]=awesome title,     // filter to posts with more than 10 likes, and a title that contains the phrase "awesome title"
&page=      1                                       // get the first page...
&pageSize=  10                                      // ...which contains 10 posts

更多的信息:
  • sorts是按逗号分隔的有序属性名列表。在名称之前添加一个“-”将切换到递减排序。
  • filters是一组以逗号分隔的{名称①}{操作符②}{值③},下面对大括号中的这三个部分做解释:①名称,是你自定义的过滤方法中的方法名称或者SieveAttribute中的Name属性的值。你还可以通过将多个名称(作为OR的逻辑)括在括号中,并使用管道分隔符,例如。(LikeCount|CommentCount)>10询问LikeCount或CommentCount是否为>10。②操作符是下面要介绍的操作符中的一种(下面会介绍)。③值是会被过滤功能所采用的值。你同样可以使用多个值(作为OR逻辑),比如[email protected]=new|hot会返回Title包含“new”或者“hot"的Post。
  • page是要返回的分页数据的页数。
  • pageSize是每一页所包含的条目数。

注意:

  • 可以使用反斜杠转义值字段中的逗号和管道
  • 可以在除{名称}或{操作符}字段之外的任何地方使用空格
  • 如果需要在应用分页之前查看数据(例如:获取总计数),使用Apply上的可选参数来延迟分页,这里有一个例子:
//代码直接摘抄自这个项目的github上面的issure中,你可以自己打开看From my own experience I‘d like the ability to get the total count while filtering and paginating.
When paginating result.Count() will be the number of records on that page, not the total number of records. This alone doesn‘t give enough information to, say, power a pagination component as we don‘t know the number of total pages/records.

Though, if I‘m wrong I‘d be pretty happy as I‘m currently doing this as a workaround:

        public async Task<IActionResult> GetQuestions(SieveModel sieveModel)
        {
            var questions = _context.Questions.AsNoTracking();
            questions = _sieveProcessor.Apply(sieveModel, questions);

            var total = _context.Questions.AsNoTracking();
            total = _sieveProcessor.Apply(sieveModel, total, applySorting: false, applyPagination: false);
            Request.HttpContext.Response.Headers.Add("X-Total-Count", total.Count().ToString());

            return Ok(questions);
        }
  • 这里有一个如何在IEnumerable上面工作的例子:
You‘ll have to write a custom filter for that. Here‘s an example for v>=1.3.7:

public class SieveCustomFilterMethods : ISieveCustomFilterMethods
{
    public IQueryable<Post> AuthorIsAnyOf(IQueryable<Post> source, string op, string value)
    {
        var result = source.Where(p => value.Split(‘|‘).Contains(p.Author));
        return result;
    }
}

Then inject the class: services.AddScoped<ISieveCustomFilterMethods, SieveCustomFilterMethods>();.

Now you can send requests in the form:

& AuthorIsAnyOf == Bad Pitt|Mel Gibson

Note I‘m using the pipe character (|) instead of a comma because Sieve uses commas to separate filter terms.
  • 另一个应用OR逻辑的例子:

    You can do that with a custom filters so for example:
    
    The equivalent of your (title, body, author)@=ABC would be [email protected]=ABC with:
    
    public class SieveCustomFilterMethods : ISieveCustomFilterMethods
    {
        public IQueryable<Post> PostSearch(IQueryable<Post> source, string op, string value)
        {
            if (op == "@=")
            {
                var result = source.Where(p => p.Title.Contains(value)
                                || p.Body.Contains(value)
                                || p.Author.Contains(value));
                return result;
            }
            else
            {
                return source;
            }
        }
    }
    
    This would save you having to send requests with the same property names repeated every time, as well as allow for any additional logic you might need.
    
    That being said, I understand the need for OR logic, especially when you need to query unknown arbitrary parameters each time. I was working on an version where a | would donate OR (similar to , currently denoting AND). I think this would allow for more complex logic than your suggested implementation - at the cost of being less concise and more redundant (ie. instead of (p1,p1)@=ABC, you‘d have [email protected]=ABC|[email protected]=ABC. Let me know what you think - would that work for your use case or am I missing something?
    
    Really glad you like Sieve :D.

原文地址:https://www.cnblogs.com/pangjianxin/p/10785615.html

时间: 2024-11-07 22:20:10

asp.net core 排序过滤分页组件:sieve(1)的相关文章

玩转ASP.NET Core中的日志组件

玩转ASP.NET Core中的日志组件简介日志组件,作为程序员使用频率最高的组件,给程序员开发调试程序提供了必要的信息.ASP.NET Core中内置了一个通用日志接口ILogger,并实现了多种内置的日志提供器,例如 ConsoleDebugEventSourceEventLogTraceSourceAzure App Service除了内置的日志提供器,ASP.NET Core还支持了多种第三方日志工具,例如 elmah.ioGelfJSNLogKissLog.netLoggrNLogSe

asp.net core MVC 过滤器之ActionFilter过滤器(二)

本系类将会讲解asp.net core MVC中的内置过滤器的使用,将分为以下章节 asp.net core MVC 过滤器之ExceptionFilter过滤器(一) asp.net core MVC 过滤器之ActionFilter过滤器(二) asp.net core MVC 过滤器之ResultFilter过滤器(三) asp.net core MVC 过滤器之ResourceFilter过滤器(四) asp.net core MVC 过滤器之AuthorizationFilter过滤器

Asp.Net Core中利用Seq组件展示结构化日志功能

在一次.Net Core小项目的开发中,掌握的不够深入,对日志记录并没有好好利用,以至于一出现异常问题,都得跑动服务器上查看,那时一度怀疑自己肯定没学好,不然这一块日志不可能需要自己扒服务器日志来查看,果然,很多东西没掌握,至此,花点时间看了下日志的相关操作.利用日志服务来查看日志数据. 本文地址:https://www.cnblogs.com/CKExp/p/9246788.html 本文Demo的地址:https://gitee.com/530521314/LogPanel.git 一.日志

ASP.Net MVC4排序检索分页的实现

前言 上一节我们做到了如下的一个基础查询页面.本节我们向这个页面中加入排序.搜索和分页功能. 排序 从上图中的地址栏中可以看到这个页面调用的是Company Controller下的Index Action.因此我们就先打开Controllers文件夹下的CompanyController.cs文件,写入如下代码: 1 using System.Linq; 2 using System.Web.Mvc; 3 using SlarkInc.DAL; 4 using System; 5 6 name

asp.net core MVC 全局过滤器之ExceptionFilter过滤器(一)

本系类将会讲解asp.net core MVC中的内置全局过滤器的使用,将分为以下章节 asp.net core MVC 过滤器之ExceptionFilter过滤器(一) asp.net core MVC 过滤器之ActionFilter过滤器(二) asp.net core MVC 过滤器之ResultFilter过滤器(三) asp.net core MVC 过滤器之ResourceFilter过滤器(四) asp.net core MVC 过滤器之AuthorizationFilter过

12.ASP.NET Core 中间件组件

这篇文章中,我将带领大家一起详细学习:ASP.NET Core Middleware Components.这篇文章中,我将详细讨论下面几个问题: 什么是ASP.NET Core 中的中间件组件? ASP.NET Core应用程序中,在哪里来使用中间件组件? 怎样来配置ASP.NET Core 应用程序中的中间件组件? 使用中间件组件的例子有哪些? ASP.NET Core应用程序中,中间件组件执行的顺序是? 什么是ASP.NET Core中间件组件? ASP.NET Core中间件组件就是组装

ASP.NET Core文章汇总

现有Asp.Net Core 文章资料,2016 3-20月汇总如下 ASP.NET Core 1.0 与 .NET Core 1.0 基础概述 http://www.cnblogs.com/Irving/p/5146976.html 初识ASP.NET Core 1.0 http://www.cnblogs.com/richieyang/p/5281761.html ASP.NET Core 行军记 -----拔营启程 http://www.cnblogs.com/wupeng/p/52892

ASP.NET Core中的ActionFilter与DI

一.简介 前几篇文章都是讲ASP.NET Core MVC中的依赖注入(DI)与扩展点的,也许大家都发现在ASP.NET CORE中所有的组件都是通过依赖注入来扩展的,而且面向一组功能就会有一组接口或抽象工厂来扩展功能,就如IControllerActivator这样的功能点在上篇文章(查看.NET Core源代码通过Autofac实现依赖注入到Controller属性)中也提到了,今天我们主要介绍一个大类似的扩展点,ASP.NET Core MVC中为我们提供了新的机制为Action Filt

ASP.NET Core 中的中间件

ASP.NET Core 中的中间件(Middleware) 在这个节中,我们将了解,ASP.NET Core 中的中间件是 什么?中间件很重要,尤其是在你想当架构师这一条路上. ASP.NET Core 中的中间件是 什么? 在 ASP.NET Core 中,中间件(Middleware)是一个可以处理 HTTP 请求或响应的软件管道. ASP.NET Core 中给中间件组件的定位是具有非常特定的用途.例如,我们可能有需要一个中间件组件验证用户,另一个中间件来处理错误,另一个中间件来提供静态