• ASP.NET Core Web API 使用DynamicLinq实现排序功能


    我是一个开发初学者,今天我想在我的web api里实现排序功能。我假设我的客户端跟微博差不多,它需要根据创建的时间来排序,创建时间越早,排序越靠后,最近创建的数据排序要靠前。

    参考资料《ASP.NET Core与RESTful API开发实战》作者:杨万青

    排序跟搜索、过滤一样,需要在传入的uri里用QueryString来传入参数,例如:
    https://localhost:5001/api/posts?pageNumber=0
    问号后面就是QueryString。

    常规方式

    大致可以这样实现,创建一个xxParameters类,里面定义QueryString的属性。我们假设我们有一个Post模型,在数据库中保存着Post数据(这个Post的意思是帖子,不是HttpPost),其中Post有一个属性是Title,我们可以定义Post的Parameters类:

    public class PostParameters
    {
        ...
        public string SortBy { get; set; } = "Title"
    }
    

    上述代码顺便为SortBy设置了默认值,按Post模型的Title属性排序。
    Post对应着一个仓储类PostReposiyoty,仓储类中实现了查询Post数据的方法,其中有一个GetAllAsync方法可以查询出所有的数据。我们给这个方法传入PostParameters类的参数,并且调用其中的SortBy属性,使用OrderBy子句实现查询:

    public Task<PagedList<Post>> GetAllAsync(PostParameters postParameters)
    {
        IQueryable<Post> queryablePosts = DbContext.Set<Post>();
        ...
        if(parameters.SortBy == "Title")
        {
            queryablePosts = queryblePosts.OrderBy(post => post.Title);
        }
        ...
    }
    
    

    使用第三方库的简易方式

    Linq的OrderBy方法不可以直接使用字符串,如:OrderBy("Title")进行排序,如果我们想要后续支持根据多个属性排序的话,要写无数个这种if语句,太麻烦。我从《ASP.NET Core与RESTful API开发实战》这本书中发现可以使用System.Linq.Dynamic.Core这个库实现动态Linq查询。支持直接使用属性名和多属性(用逗号隔开)进行排序,想要降序排序(跟微博一样,时间晚的靠前),可以在属性名后面加空格再加desc或者descending,升序的话就asc或者ascending。
    下面我们来试一下,先安装Microsoft.EntityFrameworkCore.DynamicLinq库:

    QQ图片20200423122044.png

    我们尝试使用Post的创建时间来进行排序,给Post实体模型添加一个属性:

    public DateTime CreateTime { get; set; }
    

    在Controller的HttpPost方法里处理新创建的post的时候,可以用:

    post.CreateTime = DateTime.Now;
    

    来初始化每一个新创建的post。
    然后在PostParameters里把SortBy的默认值改成"CreateTime desc",因为我们要逆序排序。
    然后在仓储类PostRepository类的GetAllAsync方法中添加:

    public Task<PagedList<Post>> GetAllAsync(PostParameters postParameters)
    {
        IQueryable<Post> queryablePosts = DbContext.Set<Post>();
        ...
        var orderedPosts = queryablePosts.OrderBy(postParameters.SortBy);
        ...
    }
    

    在这里我们只用了postParameters.SortBy作为排序的属性,如果用多个,可以用逗号隔开。而且使用OrderBy(...)的时候会报错,并且没有自动修补,需要我们手动在文件上方using System.Linq.Dynamic.Core;,这个害得我搞了半个小时才发现是这个问题,对初学者来说太坑了。
    同时排序选项也是分页元数据的一部分,别忘了生成分页元数据时返回给客户端。
    测试一下:

    QQ图片20200423130709.png

    可以看出创建时间越晚的,排序越靠前。完成。

  • 相关阅读:
    C数据结构2.1-线性表抽象数据类型
    转载的内容
    转载springboot的内容
    jQuery中的load()Failed to load resource: the server responded with a status of 404 Maven框架遇到的问题
    java代码发送邮箱源代码
    Error:(1, 10) java: 需要class, interface或enum的错误
    性能测试系列五 压测常见的关注指标以及监控分析工具
    面试官常考的Selenium Web自动化面试题总结(上篇)
    性能测试系列四 压测指标的来源
    性能测试系列三 压测方式简单总结
  • 原文地址:https://www.cnblogs.com/Kit-L/p/12760146.html
Copyright © 2020-2023  润新知