Skip to content

Instantly share code, notes, and snippets.

@syedahmad9
Last active July 27, 2022 21:54
Show Gist options
  • Save syedahmad9/bc788ee8c71490225a81f18935e7d674 to your computer and use it in GitHub Desktop.
Save syedahmad9/bc788ee8c71490225a81f18935e7d674 to your computer and use it in GitHub Desktop.
Aspnet boilerplate IQueryableExtensions to able to get Paged and Sorted data if you don't want to inherit CrudAppServiceBase Class
using System;
using System.Linq;
using System.Linq.Dynamic.Core;
using System.Threading.Tasks;
using Abp.Application.Services.Dto;
using Abp.Linq.Extensions;
using Abp.Threading;
using System.Linq.Expressions;
using Abp.Extensions;
using AutoMapper.QueryableExtensions;
using Microsoft.EntityFrameworkCore;
using Abp.ObjectMapping;
///Courtesy to https://www.csharpcodi.com/vs2/?source=4061/abplus/src/Abplus.Common/Linq/Extensions/IQueryableExtension.cs
namespace Abp.Linq.Extensions
{
public static class IQueryableExtension
{
/// <summary>
/// Apply the sorting parameters specified by Input
/// </summary>
public static IQueryable<TSource> ApplySorting<TSource, TDto>(this IQueryable<TSource> query, TDto Input)
{
//Try to sort query if available
if (Input is ISortedResultRequest sortInput && !sortInput.Sorting.IsNullOrWhiteSpace()) //有排序参数
{
return query.OrderBy(sortInput.Sorting);
}
return query;
}
/// <summary>
/// Apply the paging parameters specified by Input
/// </summary>
public static IQueryable<TSource> ApplyPaging<TSource, TDto>(this IQueryable<TSource> query, TDto Input)
{
//Try to use paging if available
if (Input is IPagedResultRequest pagedInput)
{
return query.PageBy(pagedInput);
}
return query;
}
/// <summary>
/// Sort and paginate according to Input.
/// </summary>
public static IQueryable<TSource> ApplySortingAndPaging<TSource, TDto>(this IQueryable<TSource> query, TDto Input)
{
query = query.ApplySorting(Input);
query = query.ApplyPaging(Input);
return query;
}
/// <summary>
/// Convert to an IQueryable of the specified Dto type
/// </summary>
public static IQueryable<TDto> ProjectTo<TSource, TDto>(this IQueryable<TSource> query, params Expression<Func<TDto, object>>[] membersToExpand)
{
if (query is null)
{
throw new ArgumentNullException(nameof(query));
}
if (membersToExpand is null)
{
throw new ArgumentNullException(nameof(membersToExpand));
}
return query.ProjectTo<TDto>(null, membersToExpand);
}
/// <summary>
/// Only check the list data of the specified field of Dto type
/// </summary>
/// <typeparam name="TSource">Entity Type</typeparam>
/// <typeparam name="TDto">List Dto Type</typeparam>
/// <param name="query">IQueryable of the Source Object</param>
/// <param name="Input">Query parameter (specify sort column)</param>
/// <returns>Query the list data of the specified field of Dto type</returns>
public static async Task<ListResultDto<TDto>> ToSortedListResultAsync<TSource, TDto>(this IQueryable<TSource> query, ISortedResultRequest Input, IObjectMapper objectMapper)
where TSource : class
where TDto : class
{
query = query.ApplySorting(Input);
var result = new ListResultDto<TDto>()
{
Items = await objectMapper.ProjectTo<TDto>(query).ToListAsync()
};
return result;
}
/// <summary>
/// Only check the list data of the specified field of Dto type
/// </summary>
/// <typeparam name="TSource">Entity Type</typeparam>
/// <typeparam name="TDto">List Dto Type</typeparam>
/// <param name="query">IQueryable of the Source Object</param>
/// <param name="Input">Input inherited with ISortedResultRequest</param>
/// <param name="objectMapper"></param>
/// <returns>Query the list data of the specified field of Dto type</returns>
public static ListResultDto<TDto> ToSortedListResult<TSource, TDto>(this IQueryable<TSource> query, ISortedResultRequest Input, IObjectMapper objectMapper)
where TSource : class
where TDto : class
{
return AsyncHelper.RunSync(() => query.ToSortedListResultAsync<TSource, TDto>(Input, objectMapper));
}
/// <summary>
/// After sorting and paging according to Input, convert to paging query results
/// </summary>
/// <typeparam name="TSource">Original Entity type</typeparam>
/// <typeparam name="TDto">target Dto type</typeparam>
/// <typeparam name="TSearch">Input inherited with ISortedResultRequest and IPagedResultRequest</typeparam>
/// <param name="query">IQueryable of the Source Object</param>
/// <param name="Input"></param>
/// <param name="objectMapper"></param>
/// <returns>PagedResultDto with Dto type list data</returns>
public static async Task<PagedResultDto<TDto>> ToPagedResultAsync<TSource, TDto, TSearch>(this IQueryable<TSource> query, TSearch Input, IObjectMapper objectMapper)
where TSource : class
where TDto : class
where TSearch : class
{
var pagedQuery = query.ApplySortingAndPaging(Input);
var result = new PagedResultDto<TDto>()
{
Items = await objectMapper.ProjectTo<TDto>(pagedQuery).ToListAsync()
};
//Try to use paging if available
var pagedInput = Input as IPagedResultRequest;
//When there is no paging parameter, or the result of page 1 is less than a full page, there is no need to count the total number of records
if (pagedInput == null || (pagedInput.SkipCount == 0 && result.Items.Count < pagedInput.MaxResultCount))
{
result.TotalCount = result.Items.Count;
}
else
{
result.TotalCount = await query.CountAsync();
}
return result;
}
/// <summary>
/// After sorting and paging according to Input, convert to paging query results
/// </summary>
/// <typeparam name="TSource">Original Entity type</typeparam>
/// <typeparam name="TDto">target Dto type</typeparam>
/// <param name="query"></param>
/// <param name="Input">Query parameters</param>
/// <param name="objectMapper"></param>
/// <returns></returns>
///
public static PagedResultDto<TDto> ToPagedResult<TSource, TDto, TSearch>(this IQueryable<TSource> query, TSearch Input, IObjectMapper objectMapper)
where TSource : class
where TDto : class
where TSearch : class
{
return AsyncHelper.RunSync(() => query.ToPagedResultAsync<TSource, TDto, TSearch>(Input, objectMapper));
}
}
}
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment