【ABP杂烩】Extensions后缀扩展方法

简介: 原文:【ABP杂烩】Extensions后缀扩展方法1.Extensions介绍 扩展方法使你能够向现有类型“添加”方法,而无需创建新的派生类型、重新编译或以其他方式修改原始类型。 扩展方法是一种特殊的静态方法,但可以像扩展类型上的实例方法一样进行调用。
原文: 【ABP杂烩】Extensions后缀扩展方法

1.Extensions介绍

扩展方法使你能够向现有类型“添加”方法,而无需创建新的派生类型、重新编译或以其他方式修改原始类型。 扩展方法是一种特殊的静态方法,但可以像扩展类型上的实例方法一样进行调用。 对于用 C#、F# 和 Visual Basic 编写的客户端代码,调用扩展方法与调用在类型中实际定义的方法没有明显区别。

详细见官方文档:扩展方法(C# 编程指南)

2.语法介绍

* 需要写在一个静态类中 
* 必须是一个静态方法 
* 通过第一个参数和this关键字指定扩展的目标类型 
* 不同类型的扩展方法不一定要写在同一个类中

3.事例介绍

 在ABP框架原中会发现在很多地方带有Extensions的类,其主要作用是在不改变原有接口或类的基础上扩展自定义的方法,从而方便使用,如QueryableExtensions类是对IQueryable进行扩展,里面添加了分页PageBy、条件判断WhereIf方法,代码如下:

​
using System;
using System.Linq;
using System.Linq.Expressions;
using Abp.Application.Services.Dto;

namespace Abp.Linq.Extensions
{
    /// <summary>
    /// Some useful extension methods for <see cref="IQueryable{T}"/>.
    /// </summary>
    public static class QueryableExtensions
    {
        /// <summary>
        /// Used for paging. Can be used as an alternative to Skip(...).Take(...) chaining.
        /// </summary>
        public static IQueryable<T> PageBy<T>(this IQueryable<T> query, int skipCount, int maxResultCount)
        {
            if (query == null)
            {
                throw new ArgumentNullException("query");
            }

            return query.Skip(skipCount).Take(maxResultCount);
        }

        /// <summary>
        /// Used for paging with an <see cref="IPagedResultRequest"/> object.
        /// </summary>
        /// <param name="query">Queryable to apply paging</param>
        /// <param name="pagedResultRequest">An object implements <see cref="IPagedResultRequest"/> interface</param>
        public static IQueryable<T> PageBy<T>(this IQueryable<T> query, IPagedResultRequest pagedResultRequest)
        {
            return query.PageBy(pagedResultRequest.SkipCount, pagedResultRequest.MaxResultCount);
        }

        /// <summary>
        /// Filters a <see cref="IQueryable{T}"/> by given predicate if given condition is true.
        /// </summary>
        /// <param name="query">Queryable to apply filtering</param>
        /// <param name="condition">A boolean value</param>
        /// <param name="predicate">Predicate to filter the query</param>
        /// <returns>Filtered or not filtered query based on <paramref name="condition"/></returns>
        public static IQueryable<T> WhereIf<T>(this IQueryable<T> query, bool condition, Expression<Func<T, bool>> predicate)
        {
            return condition
                ? query.Where(predicate)
                : query;
        }

        /// <summary>
        /// Filters a <see cref="IQueryable{T}"/> by given predicate if given condition is true.
        /// </summary>
        /// <param name="query">Queryable to apply filtering</param>
        /// <param name="condition">A boolean value</param>
        /// <param name="predicate">Predicate to filter the query</param>
        /// <returns>Filtered or not filtered query based on <paramref name="condition"/></returns>
        public static IQueryable<T> WhereIf<T>(this IQueryable<T> query, bool condition, Expression<Func<T, int, bool>> predicate)
        {
            return condition
                ? query.Where(predicate)
                : query;
        }
    }
}

​

 

如上所述,对IQueryable扩展后,可以像调用原生方法一样,使上层的调用感受不到区别和不用做过多的操作,方便对第三方的库进行扩展,从而增加自定义需求,有效提高项目的开发效率。调用代码如下:

 public async Task<PagedResultDto<ProjectListDto>> GetProjects(GetProjectsInput input)
        {
            var query = _projectRepository.GetAll();
            query = query
                .WhereIf(!input.Name.IsNullOrWhiteSpace(), item => item.Name.Contains(input.Name))
                .WhereIf(!input.Address.IsNullOrWhiteSpace(), item => item.Address.Contains(input.Address))
                .WhereIf(!input.ResponbleDepart.IsNullOrWhiteSpace(), item => item.ResponbleDepart.Contains(input.ResponbleDepart))
                .WhereIf(!input.Type.IsNullOrWhiteSpace(), item => item.Type.Contains(input.Type))
                .WhereIf(input.ProjectDateStart.HasValue, item => item.StartTime >= input.ProjectDateStart)
                .WhereIf(input.ProjectDateEnd.HasValue, item => item.EndTime <= input.ProjectDateEnd)
                .WhereIf(input.ReportDateStart.HasValue, item => item.ReportTime >= input.ReportDateStart)
                .WhereIf(input.ReportDateEnd.HasValue, item => item.ReportTime <= input.ReportDateEnd);


            var projectCount = await query.CountAsync();

            var projects = await query.OrderBy(input.Sorting).PageBy(input).ToListAsync();

            var projectListDtos = ObjectMapper.Map<List<ProjectListDto>>(projects);

            return new PagedResultDto<ProjectListDto>(
                projectCount,
                projectListDtos
                );
        }

  

目录
相关文章
|
1月前
|
传感器 人工智能 JavaScript
Playwright实战:写UI自动化脚本,速度直接起飞
简介: 测试工程师老王因UI自动化问题深夜奋战,反映出传统测试工具的局限性。微软开源的Playwright凭借智能等待、跨域操作、移动端模拟与网络拦截等强大功能,正迅速取代Selenium,成为新一代自动化测试标准。其稳定高效的设计显著降低维护成本,助力企业构建高质量测试流程。
|
5月前
|
存储 人工智能 自然语言处理
LangChain RAG入门教程:构建基于私有文档的智能问答助手
本文介绍如何利用检索增强生成(RAG)技术与LangChain框架构建基于特定文档集合的AI问答系统。通过结合检索系统和生成机制,RAG能有效降低传统语言模型的知识局限与幻觉问题,提升回答准确性。文章详细展示了从环境配置、知识库构建到系统集成的全流程,并提供优化策略以改进检索与响应质量。此技术适用于专业领域信息检索与生成,为定制化AI应用奠定了基础。
1242 5
LangChain RAG入门教程:构建基于私有文档的智能问答助手
|
11月前
|
人工智能
开启歌词创作之门:写歌词的技巧和方法详解,妙笔生词AI智能写歌词软件
歌词创作是通往音乐灵魂深处的大门。本文介绍了一些实用技巧,如借助《妙笔生词智能写歌词软件》的AI功能,捕捉生活中的灵感,确定主题,合理安排歌词结构,运用生动的语言和修辞手法,确保韵律和节奏,帮助你轻松开启创作之旅。
|
SQL 存储 大数据
更改 HIVE 表字段数据类型有哪些注意事项?
更改 HIVE 表字段数据类型有哪些注意事项?
|
存储 JSON 小程序
【小程序云开发】不用后端也能构建完整的微信小程序
本文介绍了如何从零开始学习和掌握微信小程序云开发,包括云函数、云数据库和HTTP触发等重要概念。通过详细的步骤和示例,读者将学会如何创建和部署云函数,以及如何使用云数据库来存储和管理小程序的数据。同时,本文还介绍了如何通过HTTP触发器实现小程序与外部API的数据交互,从而为小程序开发提供更灵活、高效的后端解决方案。无论您是初学者还是有一定经验的开发者,本文都将帮助您轻松掌握微信小程序云开发,并为您的小程序开发项目提供更多可能性。
2498 0
|
人工智能 运维 Serverless
函数计算产品使用问题之上传模型文件占用的是什么空间
函数计算产品作为一种事件驱动的全托管计算服务,让用户能够专注于业务逻辑的编写,而无需关心底层服务器的管理与运维。你可以有效地利用函数计算产品来支撑各类应用场景,从简单的数据处理到复杂的业务逻辑,实现快速、高效、低成本的云上部署与运维。以下是一些关于使用函数计算产品的合集和要点,帮助你更好地理解和应用这一服务。
166 2
|
存储 算法 数据可视化
|
Ubuntu 安全 虚拟化
vmware虚拟机运行ubuntu等卡慢的解决办法
vmware虚拟机运行ubuntu等卡慢的解决办法
3474 0
|
Java C# 决策智能
运筹优化学习09:一个示例带你入门如何使用C++、C#、Java、Python、Matlab调用Cplex(下)
运筹优化学习09:一个示例带你入门如何使用C++、C#、Java、Python、Matlab调用Cplex
运筹优化学习09:一个示例带你入门如何使用C++、C#、Java、Python、Matlab调用Cplex(下)
|
Cloud Native 物联网 编译器
gRPC(三)基础:gRPC快速入门
Protobuf 是 Google 的序列化/反序列化协议,可以轻松定义服务和自动生成客户端库。gRPC 使用此协议作为其接口定义语言 (IDL) 和序列化工具集。
559 0
gRPC(三)基础:gRPC快速入门