首页 星云 工具 资源 星选 资讯 热门工具
:

PDF转图片 完全免费 小红书视频下载 无水印 抖音视频下载 无水印 数字星空

Sy.ExpressionBuilder 动态查询新体验

编程知识
2024年08月14日 09:45

省流模式,看下对比

复制代码
 //常规查询
                var query = users
                    .WhereIf(m => m.UserName.Contains(input.UserName), !string.IsNullOrEmpty(input.UserName))
                    .WhereIf(m => input.RoleIds.Contains(m.RoleId), input.RoleIds?.Any() ?? false)
                    .WhereIf(m => m.Role.RoleName.Contains(input.RoleName), !string.IsNullOrEmpty(input.RoleName))
                    .WhereIf(m => m.Sys.Any(p => p.SysName.Contains(input.SysName)), !string.IsNullOrEmpty(input.SysName))
                    .WhereIf(m => m.Gender == input.Gender, input.Gender.HasValue)
                    .WhereIf(m => m.CreateTime >= input.CreateTimeStart, input.CreateTimeStart.HasValue)
                    .WhereIf(m => m.CreateTime <= input.CreateTimeEnd, input.CreateTimeEnd.HasValue);
                var list = query
                    .OrderBy(m => m.RoleId).ThenBy(m => m.Tel)
                    .Skip((input.Page - 1) * input.PageSize).Take(input.PageSize)
                    .ToList();
                var total = query.Count();
            } {
                //构造器查询方式1
                var (list, total) =
                    users.ToPageList(input.AddMultipleOrderBy(false, nameof(User.RoleId), nameof(User.Tel)));
                //构造器查询方式2
                var (list2, total2) = users
                    .WhereExt(input) //.Where(input.ToExpression<User>())
                    .OrderBy(false, nameof(User.RoleId), nameof(User.Tel)
                    )
                    .Page(input);
            }
复制代码

没兴趣?那本博客到此结束。小伙伴可以到别处看看了(吐槽下,博客园的这个发布机制属实是看人脸皮和自信度了,我属于脸皮厚的,敢自己推首页)。

1.该表达式插件通过模型继承获取对应的能力。目前提供的模型有

  1. QueryModel :基础查询类

  2. PageModel:分页查询参数类(默认每页分页20条)

  3. FullQueryModel:查询模型,对比QueryModel 多了查询集合QueryItems和过滤FilterFields。前端可以在后端给与的基础上,添加查询参数,对于前端来说权限有点大,慎用(建议高级查询的时候用)。

  4. FullPageModel:查询模型,对比PageModel多了查询集合QueryItems和过滤FilterFields。慎用(原因同上)。

2.属性名约束

  1. 编号查询:编号查询最好是以Id结尾,不然如果编号为字符串的话,查询方式会以Contains形式查询。

  2. 时间格式:以 Start,End 结尾 ,生成条件为 >= 和<=。

  3. 数字范围:属性名称 以 Min,Max 结尾 ,生成条件为 >= 和<=。

  4. 字符串查询: 名字需要和表字段一致,生成条件为 Contains

3.特性约束。这部分主要为了弥补属性名的不足。可以使用特性ConditionAttribute。下面给出参数介绍以及使用例子。

  • 属性名:PropertyName

  • 属性值:Value

  • 查询方法:Condition

  • 查询类型:ConditionType(and/or)

  • 是否唯一属性名称:IsSinglePropertyName

  • 是否区分大小写:IsCaseSensitive

使用范例
  1. 导航父类查询:父类类名+英文符号.+父类的属性名。如

  [Condition($"{nameof(NewType)}.{nameof(NewType.Name)}")]
  public string Name { get; set; }
  1. 导航子类查询:子类类名+括号[子类属性名]。如

  [Condition($"{nameof(NewType)}[{nameof(NewType.Name)}]")]
  public string Name { get; set; }
  1. 默认的属性名不符合自己的规则的查询:例如字符串想要正值匹配,可通过特性配置

 [Condition("Role.RoleName", EnumCondition.Equal, EnumConditionType.And)]
  public string Name { get; set; }

4.排序处理

  1. 默认排序方法 DefaultOrderBy(string propName, bool isDesc = true, bool isClearReserved = true)。参数解析:属性名、降序升序、是否清掉之前的排序

  2. 默认排序方法 AddOrderBy(string propName, bool isDesc = true)。参数解析:属性名、降序升序。可添加多个,优先级按照,添加的顺序来。

复制代码
/// <summary>
    /// 设置默认的排序条件,并清空之前保留的排序条件(如果isClearReserved为true)。
    /// </summary>
    /// <param name="input">当前的QueryModel实例。</param>
    /// <param name="propName">要排序的属性名。</param>
    /// <param name="isDesc">排序方向,true为降序,false为升序。</param>
    /// <param name="isClearReserved">是否清空之前保留的排序条件。</param>
    /// <returns>返回修改后的QueryModel实例。</returns>
    public static QueryModel DefaultOrderBy(this QueryModel input, string propName, bool isDesc, bool isClearReserved)
    {
         // 方法实现
    }
​
    /// <summary>
    /// 向QueryModel中添加一个排序条件。
    /// </summary>
    /// <param name="input">当前的QueryModel实例。</param>
    /// <param name="propName">要排序的属性名。</param>
    /// <param name="isDesc">排序方向,true为降序,false为升序。</param>
    /// <returns>返回修改后的QueryModel实例。</returns>
    public static QueryModel AddOrderBy(this QueryModel input, string propName, bool isDesc)
    {
         // 方法实现
    }
​
    /// <summary>
    /// 向QueryModel中添加两个排序条件。
    /// </summary>
    /// <param name="input">当前的QueryModel实例。</param>
    /// <param name="propName">第一个要排序的属性名。</param>
    /// <param name="isDesc">第一个排序的方向,true为降序,false为升序。</param>
    /// <param name="propName2">第二个要排序的属性名。</param>
    /// <param name="isDesc2">第二个排序的方向,true为降序,false为升序。</param>
    /// <returns>返回修改后的QueryModel实例。</returns>
    public static QueryModel AddOrderBy(this QueryModel input, string propName, bool isDesc, string propName2, bool isDesc2)
    {
          // 方法实现
    }
​
    /// <summary>
    /// 向QueryModel中添加三个排序条件。
    /// </summary>
    /// <param name="input">当前的QueryModel实例。</param>
    /// <param name="propName">第一个要排序的属性名。</param>
    /// <param name="isDesc">第一个排序的方向,true为降序,false为升序。</param>
    /// <param name="propName2">第二个要排序的属性名。</param>
    /// <param name="isDesc2">第二个排序的方向,true为降序,false为升序。</param>
    /// <param name="propName3">第三个要排序的属性名。</param>
    /// <param name="isDesc3">第三个排序的方向,true为降序,false为升序。</param>
    /// <returns>返回修改后的QueryModel实例。</returns>
    public static QueryModel AddOrderBy(this QueryModel input, string propName, bool isDesc, string propName2, bool isDesc2, string propName3, bool isDesc3)
    {
        // 方法实现
    }
    
    /// <summary>
    /// 向QueryModel实例中添加一组排序条件。
    /// </summary>
    /// <param name="input">当前的QueryModel实例。</param>
    /// <param name="orderByItems">包含排序信息的OrderByItem列表。</param>
    /// <returns>返回修改后的QueryModel实例(在空实现中,实际上只是返回传入的实例)。</returns>
    public static QueryModel AddOrderBy(this QueryModel input, List<OrderByItem> orderByItems)
    {
       // 方法实现
    }
​
    /// <summary>
    /// 向QueryModel实例中添加多个排序条件,所有条件使用相同的排序方向。
    /// </summary>
    /// <param name="input">当前的QueryModel实例。</param>
    /// <param name="isDesc">排序方向,true为降序,false为升序。</param>
    /// <param name="propNames">要排序的属性名数组。</param>
    /// <returns>返回修改后的QueryModel实例(在空实现中,实际上只是返回传入的实例)。</returns>
    public static QueryModel AddMultipleOrderBy(this QueryModel input, bool isDesc, params string[] propNames)
    {
         // 方法实现
    }
复制代码

5.分组查询

  1. 使用特性GroupAttribute。使用分组序号,如Group(1)、如Group(1,EnumConditionType.Or)。

   [Group(1)]
   public string Name { get; set; }
    
   [Group(1, EnumConditionType.Or)]
   public string UserName { get; set; }

6.时间跨度查询约束

  1. 使用特性DurationAttribute。在时间的两个属性之间中的一个打上这个特性即可。如时间跨度三个月的。

    复制代码
    /// <summary>
    /// 创建时间 开始
    /// </summary>
    [Duration(3, EnumTimeType.Month)]
    public DateTime? CreateTimeStart { get; set; }
    /// <summary>
    /// 创建时间  结束
    /// </summary>
    public DateTime? CreateTimeEnd { get; set; }
    复制代码

7.分页配置

  1. 没啥好说的:PageIndex 当前页 ,PageSize 显示数。

8.参数忽略

  1. 提供了特性NotQueryAttribute,在对于属性添加即可忽略构建查询。

9.构建表达式

  1. 只要类继承了QueryModel等这四个模型,即可以通过ToExpression<TSource>(),构建对于自己模型的表达式。

10.查询扩展

  1. 常规扩展,根据传入的4大模型过滤。例如

复制代码
 /// <summary>
    /// 查询扩展
    /// </summary>
    public static IQueryable<T> WhereExt<T>(this IQueryable<T> source, QueryModel input)
    {
        // 
    }
    /// <summary>
    /// 查询扩展,并排序
    /// </summary>
    public static IQueryable<T> WhereExt<T>(this IQueryable<T> source, Expression<Func<T,       bool>> expression, params OrderByItem[] orderByItems)
    {
      // 
    }  
复制代码
  1. 部分查询扩展,可返回传入的模型类(如果属性匹配得上的话)

复制代码
        /// <summary>
        /// Select扩展方法
        /// </summary>
        /// <typeparam name="TSource"></typeparam>
        /// <typeparam name="TTarget"></typeparam>
        /// <param name="query"></param>
        /// <returns></returns>
        public static IQueryable<TTarget> Select<TSource, TTarget>(this IQueryable<TSource> query)
        {
             
        }
复制代码
  1. IQueryable扩展方法

复制代码
/// <summary>
/// 根据QueryModel中的条件过滤IQueryable<T>并返回结果列表。 
/// </summary>
/// <param name="source">待处理的IQueryable<T>。</param>
/// <param name="input">包含过滤条件的QueryModel。</param>
/// <returns>未经过滤的T类型列表。</returns>
public static List<T> ToList<T>(this IQueryable<T> source, QueryModel input)
{
    // 实现
}

/// <summary>
/// 根据FullQueryModel中的复杂条件过滤IQueryable<T>并返回结果列表。 
/// </summary>
/// <param name="source">待处理的IQueryable<T>。</param>
/// <param name="input">包含复杂过滤条件的FullQueryModel。</param>
/// <returns>未经过滤的T类型列表。</returns>
public static List<T> ToList<T>(this IQueryable<T> source, FullQueryModel input)
{
    // 实现
}

/// <summary>
/// 根据PageModel中的分页参数对IQueryable<T>进行分页处理,并返回包含数据列表和总记录数的元组。
/// </summary>
/// <param name="query">待分页处理的IQueryable<T>。</param>
/// <param name="input">包含分页参数的PageModel。</param>
/// <returns>包含未分页数据列表和未计算总记录数的元组。</returns>
public static (List<T> list, int total) ToPageList<T>(this IQueryable<T> query, PageModel input)
{
    // 实现
}

/// <summary>
/// 根据FullPageModel中的分页和过滤条件对IQueryable<T>进行处理,并返回包含数据列表和总记录数的元组
/// </summary>
/// <param name="query">待处理的IQueryable<T>。</param>
/// <param name="input">包含分页和过滤条件的FullPageModel。</param>
/// <returns>包含未分页且未过滤的数据列表和未计算总记录数的元组。</returns>
public static (List<T> list, int total) ToPageList<T>(this IQueryable<T> query, FullPageModel input)
{
    // 实现
}

/// <summary>
/// 对IQueryable<T>进行分页处理,并返回包含数据列表和总记录数的元组。
/// </summary>
/// <param name="query">待分页处理的IQueryable<T>。</param>
/// <param name="input">包含分页参数的PageModel。</param>
/// <returns>包含未分页数据列表和未计算总记录数的元组。</returns>
public static (List<T> list, int total) Page<T>(this IQueryable<T> query, PageModel input)
{
    // 实现
}

/// <summary>
/// 根据FullPageModel中的分页和过滤条件对IQueryable<T>进行处理,并返回包含数据列表和总记录数的元组。
/// </summary>
/// <param name="query">待处理的IQueryable<T>。</param>
/// <param name="input">包含分页和过滤条件的FullPageModel。</param>
/// <returns>包含未分页且未过滤的数据列表和未计算总记录数的元组。</returns>
public static (List<T> list, int total) Page<T>(this IQueryable<T> query, FullPageModel input)
{
    // 实现
}
/// <summary>
/// 根据PageModel中的分页和排序参数对IQueryable<T>进行分页和排序处理,并返回包含排序后数据列表和总记录数的元组。
/// </summary>
/// <param name="query">待分页和排序处理的IQueryable<T>。</param>
/// <param name="input">包含分页和排序参数的PageModel。</param>
/// <returns>包含未分页且未排序的数据列表和未计算总记录数的元组。</returns>
public static (List<T> list, int total) OrderPageList<T>(this IQueryable<T> query, PageModel input)
{
    // 实现
}

/// <summary>
/// 根据FullPageModel中的分页、排序和过滤条件对IQueryable<T>进行处理,并返回包含排序后数据列表和总记录数的元组。
/// </summary>
/// <param name="query">待处理的IQueryable<T>。</param>
/// <param name="input">包含分页、排序和过滤条件的FullPageModel。</param>
/// <returns>包含未分页、未排序且未过滤的数据列表和未计算总记录数的元组。</returns>
public static (List<T> list, int total) OrderPageList<T>(this IQueryable<T> query, FullPageModel input)
{
    // 实现
}
复制代码
  1. IQueryable扩展方法之排序

复制代码
/// <summary>
/// 根据单个属性名对IQueryable<TEntity>进行排序。
/// </summary>
/// <param name="input">待排序的IQueryable<TEntity>。</param>
/// <param name="propName">要排序的属性名。</param>
/// <param name="isDesc">指示排序是否为降序。</param>
/// <returns>未应用排序的IQueryable<TEntity>。</returns>
public static IQueryable<TEntity> OrderBy<TEntity>(this IQueryable<TEntity> input, string propName, bool isDesc)
{
  // 实现
}

/// <summary>
/// 根据两个属性名对IQueryable<TEntity>进行排序。
/// </summary>
/// <param name="input">待排序的IQueryable<TEntity>。</param>
/// <param name="propName">第一个要排序的属性名。</param>
/// <param name="isDesc">第一个排序是否为降序。</param>
/// <param name="propName2">第二个要排序的属性名。</param>
/// <param name="isDesc2">第二个排序是否为降序。</param>
/// <returns>未应用排序的IQueryable<TEntity>。</returns>
public static IQueryable<TEntity> OrderBy<TEntity>(this IQueryable<TEntity> input, string propName, bool isDesc, string propName2, bool isDesc2)
{
  // 实现
}

/// <summary>
/// 根据三个属性名对IQueryable<TEntity>进行排序。
/// </summary>
/// <param name="input">待排序的IQueryable<TEntity>。</param>
/// <param name="propName">第一个要排序的属性名。</param>
/// <param name="isDesc">第一个排序是否为降序。</param>
/// <param name="propName2">第二个要排序的属性名。</param>
/// <param name="isDesc2">第二个排序是否为降序。</param>
/// <param name="propName3">第三个要排序的属性名。</param>
/// <param name="isDesc3">第三个排序是否为降序。</param>
/// <returns>未应用排序的IQueryable<TEntity>。</returns>
public static IQueryable<TEntity> OrderBy<TEntity>(this IQueryable<TEntity> input, string propName, bool isDesc, string propName2, bool isDesc2, string propName3, bool isDesc3)
{
  // 实现
}

/// <summary>
/// 根据多个属性名对IQueryable<TEntity>进行排序。属性名和排序方向通过数组提供。
/// </summary>
/// <param name="input">待排序的IQueryable<TEntity>。</param>
/// <param name="isDesc">是否所有排序都应为降序,此参数在可变参数场景下可能不被直接使用,而是作为方法重载的标识。</param>
/// <param name="propNames">要排序的属性名数组。</param>
/// <returns>未应用排序的IQueryable<TEntity>。</returns>
public static IQueryable<TEntity> OrderBy<TEntity>(this IQueryable<TEntity> input, bool isDesc, params string[] propNames)
{
  // 实现
}

/// <summary>
/// 根据IQueryModel中的排序信息对IQueryable<TEntity>进行排序。
/// </summary>
/// <param name="input">待排序的IQueryable<TEntity>。</param>
/// <param name="queryModel">包含排序信息的IQueryModel。</param>
/// <returns>未应用排序的IQueryable<TEntity>。</returns>
public static IQueryable<TEntity> OrderBy<TEntity>(this IQueryable<TEntity> input, IQueryModel queryModel)
{
   // 实现
}

/// <summary>
/// 根据OrderByItem数组中的排序项对IQueryable<TEntity>进行排序。
/// </summary>
/// <param name="input">待排序的IQueryable<TEntity>。</param>
/// <param name="orderByItems">包含排序属性和排序方向的OrderByItem数组。</param>
/// <returns>未应用排序的IQueryable<TEntity>。</returns>
public static IQueryable<TEntity> OrderBy<TEntity>(this IQueryable<TEntity> input, params OrderByItem[] orderByItems)
{
   // 实现
}

/// <summary>
/// 根据OrderByItem列表中的排序项对IQueryable<TEntity>进行排序。
/// </summary>
/// <param name="input">待排序的IQueryable<TEntity>。</param>
/// <param name="orderByItems">包含排序属性和排序方向的OrderByItem列表。</param>
/// <returns>未应用排序的IQueryable<TEntity>。</returns>
public static IQueryable<TEntity> OrderBy<TEntity>(this IQueryable<TEntity> input, List<OrderByItem> orderByItems)
{
   // 实现
}
From:https://www.cnblogs.com/noert/p/18358413
本文地址: http://www.shuzixingkong.net/article/1085
0评论
提交 加载更多评论
其他文章 .NET 8 中利用 MediatR 实现高效消息传递
前言 MediatR 是 .NET 下的一个实现消息传递的库,轻量级、简洁高效,用于实现进程内的消息传递机制。它基于中介者设计模式,支持请求/响应、命令、查询、通知和事件等多种消息传递模式。通过泛型支持,MediatR 可以智能地调度不同类型的消息,非常适合用于领域事件处理。 在本文中,将通过一个简
.NET 8 中利用 MediatR 实现高效消息传递 .NET 8 中利用 MediatR 实现高效消息传递 .NET 8 中利用 MediatR 实现高效消息传递
聊一聊 Netty 数据搬运工 ByteBuf 体系的设计与实现
本文基于 Netty 4.1.56.Final 版本进行讨论 时光芿苒,岁月如梭,好久没有给大家更新 Netty 相关的文章了,在断更 Netty 的这段日子里,笔者一直在持续更新 Linux 内存管理相关的文章 ,目前为止,算是将 Linux 内存管理子系统相关的主干源码较为完整的给大家呈现了出来
聊一聊 Netty 数据搬运工 ByteBuf 体系的设计与实现 聊一聊 Netty 数据搬运工 ByteBuf 体系的设计与实现 聊一聊 Netty 数据搬运工 ByteBuf 体系的设计与实现
SpringBoot 整合线程池
分为三步 启动类加 @EnableAsync 注解 在方法上加 @Async 注解 创建线程池配置类 1.启动类加 @EnableAsync 注解 @SpringBootApplication @EnableAsync public class FacadeH5Application { publi
深入理解微服务中的负载均衡算法与配置策略
今天,我们主要补充了上一章关于微服务通信的内容,并深入探讨了负载均衡算法的重要性。我们首先详细讨论了Ribbon默认使用的负载均衡算法。尽管在本地测试时可能会观察到轮询的效果,但简单依赖这种表面的观察是不够的。在真实的生产环境中,特别是在跨多个数据中心部署时,负载均衡策略的选择需要更加深入的理解和分
深入理解微服务中的负载均衡算法与配置策略 深入理解微服务中的负载均衡算法与配置策略
面试官:说说volatile应用和实现原理?
volatile 是并发编程中的重要关键字,它的名气甚至是可以与 synchronized、ReentrantLock 等齐名,也是属于并发编程五杰之一。 需要注意的是 volatile 并不能保证原子性,因此使用 volatile 并没有办法保证线程安全。 并发编程五杰: PS:“并发编程五杰”是
面试官:说说volatile应用和实现原理? 面试官:说说volatile应用和实现原理?
老弟想自己做个微信,被我一个问题劝退了。。
大家好,我是程序员鱼皮。最近老弟小阿巴放暑假,想找点事情做,于是就来问我:老鲏,我想做个练手项目,有没有什么好的建议? 我说:练手项目的话,就做个自己感兴趣的呗,想加什么功能就加什么,做起来会更舒服~ 小阿巴:Emm,我感兴趣的太多了,有没有推荐啊? 我说:那就想想自己经常使用的网站或 APP,选个
老弟想自己做个微信,被我一个问题劝退了。。 老弟想自己做个微信,被我一个问题劝退了。。 老弟想自己做个微信,被我一个问题劝退了。。
将 Rust 代码编译为 WASM
前言 在现代 Web 开发中,WebAssembly (WASM) 已成为一种强大的工具。它使得开发者可以在浏览器中运行高性能的代码,跨越传统的 JavaScript 性能限制。Rust 语言因其高效性和内存安全性,成为了编写 WASM 模块的热门选择。本文将介绍如何将 Rust 代码编译为 Web
附038.Kubernetes_v1.30.3高可用部署架构二
部署组件 该 Kubernetes 部署过程中,对于部署环节,涉及多个组件,主要有 kubeadm 、kubelet 、kubectl。 kubeadm介绍 Kubeadm 为构建 Kubernetes 提供了便捷、高效的“最佳实践” ,该工具提供了初始化完整 Kubernetes 过程所需的组件,
附038.Kubernetes_v1.30.3高可用部署架构二 附038.Kubernetes_v1.30.3高可用部署架构二 附038.Kubernetes_v1.30.3高可用部署架构二