feat: add sorting to countries controller
This commit is contained in:
parent
cf98f958ac
commit
4b5462e889
6
Server/Helpers/ISortHelper.cs
Normal file
6
Server/Helpers/ISortHelper.cs
Normal file
@ -0,0 +1,6 @@
|
|||||||
|
namespace Server.Helpers;
|
||||||
|
|
||||||
|
public interface ISortHelper<T>
|
||||||
|
{
|
||||||
|
IQueryable<T> ApplySort(IQueryable<T> entities, string? orderByQueryString);
|
||||||
|
}
|
46
Server/Helpers/SortHelper.cs
Normal file
46
Server/Helpers/SortHelper.cs
Normal file
@ -0,0 +1,46 @@
|
|||||||
|
using System.Linq.Dynamic.Core;
|
||||||
|
using System.Reflection;
|
||||||
|
using System.Text;
|
||||||
|
|
||||||
|
namespace Server.Helpers;
|
||||||
|
|
||||||
|
public class SortHelper<T> : ISortHelper<T>
|
||||||
|
{
|
||||||
|
public IQueryable<T> ApplySort(IQueryable<T> entities, string? orderByQueryString)
|
||||||
|
{
|
||||||
|
if (!entities.Any() || String.IsNullOrWhiteSpace(orderByQueryString))
|
||||||
|
{
|
||||||
|
return entities;
|
||||||
|
}
|
||||||
|
|
||||||
|
var orderParams = orderByQueryString.Trim().Split(",");
|
||||||
|
var propertyInfos =
|
||||||
|
typeof(T).GetProperties(BindingFlags.Public | BindingFlags.Instance);
|
||||||
|
var orderQueryBuilder = new StringBuilder();
|
||||||
|
|
||||||
|
foreach (var param in orderParams)
|
||||||
|
{
|
||||||
|
if (string.IsNullOrWhiteSpace(param))
|
||||||
|
{
|
||||||
|
continue;
|
||||||
|
}
|
||||||
|
|
||||||
|
var propertyFromQueryName = param[0] == '-' || param[0] == '+' ? param.Substring(1) : param;
|
||||||
|
var objectProperty = propertyInfos.FirstOrDefault(pi =>
|
||||||
|
pi.Name.Equals(propertyFromQueryName, StringComparison.InvariantCultureIgnoreCase));
|
||||||
|
|
||||||
|
if (objectProperty == null)
|
||||||
|
{
|
||||||
|
continue;
|
||||||
|
}
|
||||||
|
|
||||||
|
var sortingOrder = param[0] == '-' ? "descending" : "ascending";
|
||||||
|
|
||||||
|
orderQueryBuilder.Append($"{objectProperty.Name} {sortingOrder}, ");
|
||||||
|
}
|
||||||
|
|
||||||
|
var orderQuery = orderQueryBuilder.ToString().TrimEnd(',', ' ');
|
||||||
|
|
||||||
|
return entities.OrderBy(orderQuery);
|
||||||
|
}
|
||||||
|
}
|
@ -7,6 +7,7 @@ using Microsoft.OpenApi.Models;
|
|||||||
using Newtonsoft.Json;
|
using Newtonsoft.Json;
|
||||||
using Server.Configurations;
|
using Server.Configurations;
|
||||||
using Server.Data;
|
using Server.Data;
|
||||||
|
using Server.Helpers;
|
||||||
using Server.Models;
|
using Server.Models;
|
||||||
using Server.Services;
|
using Server.Services;
|
||||||
|
|
||||||
@ -82,8 +83,11 @@ builder.Services.AddAuthorization();
|
|||||||
builder.Services.AddAutoMapper(typeof(MapperInitializer));
|
builder.Services.AddAutoMapper(typeof(MapperInitializer));
|
||||||
|
|
||||||
builder.Services.AddScoped<ICountryManagementService, CountryManagementService>();
|
builder.Services.AddScoped<ICountryManagementService, CountryManagementService>();
|
||||||
|
|
||||||
builder.Services.AddScoped<IDateTimeService, DateTimeService>();
|
builder.Services.AddScoped<IDateTimeService, DateTimeService>();
|
||||||
|
|
||||||
|
builder.Services.AddScoped<ISortHelper<Country>, SortHelper<Country>>();
|
||||||
|
|
||||||
// Adding DB Context with PostgreSQL
|
// Adding DB Context with PostgreSQL
|
||||||
var connectionString = builder.Configuration.GetConnectionString("DefaultConnection");
|
var connectionString = builder.Configuration.GetConnectionString("DefaultConnection");
|
||||||
builder.Services.AddDbContext<ApplicationDbContext>(options =>
|
builder.Services.AddDbContext<ApplicationDbContext>(options =>
|
||||||
|
@ -27,6 +27,7 @@
|
|||||||
<PackageReference Include="Npgsql.EntityFrameworkCore.PostgreSQL" Version="6.0.7" />
|
<PackageReference Include="Npgsql.EntityFrameworkCore.PostgreSQL" Version="6.0.7" />
|
||||||
<PackageReference Include="Swashbuckle.AspNetCore" Version="6.4.0" />
|
<PackageReference Include="Swashbuckle.AspNetCore" Version="6.4.0" />
|
||||||
<PackageReference Include="System.IdentityModel.Tokens.Jwt" Version="6.23.1" />
|
<PackageReference Include="System.IdentityModel.Tokens.Jwt" Version="6.23.1" />
|
||||||
|
<PackageReference Include="System.Linq.Dynamic.Core" Version="1.2.20" />
|
||||||
</ItemGroup>
|
</ItemGroup>
|
||||||
|
|
||||||
<ItemGroup>
|
<ItemGroup>
|
||||||
|
@ -1,7 +1,9 @@
|
|||||||
|
using System.Linq.Dynamic.Core;
|
||||||
using AutoMapper;
|
using AutoMapper;
|
||||||
using AutoMapper.QueryableExtensions;
|
using AutoMapper.QueryableExtensions;
|
||||||
using Microsoft.EntityFrameworkCore;
|
using Microsoft.EntityFrameworkCore;
|
||||||
using Server.Data;
|
using Server.Data;
|
||||||
|
using Server.Helpers;
|
||||||
using Server.Models;
|
using Server.Models;
|
||||||
using SharedModels.DataTransferObjects;
|
using SharedModels.DataTransferObjects;
|
||||||
using SharedModels.QueryStringParameters;
|
using SharedModels.QueryStringParameters;
|
||||||
@ -12,12 +14,14 @@ public class CountryManagementService : ICountryManagementService
|
|||||||
{
|
{
|
||||||
private readonly ApplicationDbContext _dbContext;
|
private readonly ApplicationDbContext _dbContext;
|
||||||
private readonly IMapper _mapper;
|
private readonly IMapper _mapper;
|
||||||
|
private readonly ISortHelper<Country> _countrySortHelper;
|
||||||
|
|
||||||
public CountryManagementService(ApplicationDbContext dbContext,
|
public CountryManagementService(ApplicationDbContext dbContext,
|
||||||
IMapper mapper)
|
IMapper mapper, ISortHelper<Country> countrySortHelper)
|
||||||
{
|
{
|
||||||
_dbContext = dbContext;
|
_dbContext = dbContext;
|
||||||
_mapper = mapper;
|
_mapper = mapper;
|
||||||
|
_countrySortHelper = countrySortHelper;
|
||||||
}
|
}
|
||||||
|
|
||||||
public async Task<(bool isSucceed, string message, CountryDto country)> AddCountry(CreateCountryDto createCountryDto)
|
public async Task<(bool isSucceed, string message, CountryDto country)> AddCountry(CreateCountryDto createCountryDto)
|
||||||
@ -36,14 +40,27 @@ public class CountryManagementService : ICountryManagementService
|
|||||||
var dbCountries = _dbContext.Countries.AsQueryable();
|
var dbCountries = _dbContext.Countries.AsQueryable();
|
||||||
|
|
||||||
SearchByAllCountryFields(ref dbCountries, parameters.Search);
|
SearchByAllCountryFields(ref dbCountries, parameters.Search);
|
||||||
SearchByCountryCode(ref dbCountries, parameters.CountryCode);
|
SearchByCountryCode(ref dbCountries, parameters.Code);
|
||||||
SearchByCountryName(ref dbCountries, parameters.CountryName);
|
SearchByCountryName(ref dbCountries, parameters.Name);
|
||||||
|
|
||||||
|
try
|
||||||
|
{
|
||||||
|
dbCountries = _countrySortHelper.ApplySort(dbCountries, parameters.Sort);
|
||||||
|
|
||||||
|
// By calling Any() we will check if LINQ to Entities Query will be
|
||||||
|
// executed. If not it will throw an InvalidOperationException exception
|
||||||
|
var isExecuted = dbCountries.Any();
|
||||||
|
}
|
||||||
|
catch (Exception e)
|
||||||
|
{
|
||||||
|
return (false, "Invalid sorting string", null, null)!;
|
||||||
|
}
|
||||||
|
|
||||||
var pagingMetadata = ApplyPaging(ref dbCountries, parameters.PageNumber,
|
var pagingMetadata = ApplyPaging(ref dbCountries, parameters.PageNumber,
|
||||||
parameters.PageSize);
|
parameters.PageSize);
|
||||||
|
|
||||||
var countryDtos = dbCountries.ToList()
|
var countryDtos =
|
||||||
.ConvertAll(c => _mapper.Map<CountryDto>(c));
|
dbCountries.ProjectTo<CountryDto>(_mapper.ConfigurationProvider);
|
||||||
|
|
||||||
return (true, "", countryDtos, pagingMetadata);
|
return (true, "", countryDtos, pagingMetadata);
|
||||||
|
|
||||||
|
@ -2,6 +2,11 @@ namespace SharedModels.QueryStringParameters;
|
|||||||
|
|
||||||
public class CountryParameters : QueryStringParameters
|
public class CountryParameters : QueryStringParameters
|
||||||
{
|
{
|
||||||
public string? CountryCode { get; set; }
|
public CountryParameters()
|
||||||
public string? CountryName { get; set; }
|
{
|
||||||
|
Sort = "id";
|
||||||
|
}
|
||||||
|
|
||||||
|
public string? Code { get; set; }
|
||||||
|
public string? Name { get; set; }
|
||||||
}
|
}
|
@ -13,4 +13,5 @@ public class QueryStringParameters
|
|||||||
}
|
}
|
||||||
|
|
||||||
public string? Search { get; set; }
|
public string? Search { get; set; }
|
||||||
|
public string? Sort { get; set; }
|
||||||
}
|
}
|
Loading…
Reference in New Issue
Block a user