Skip to content
This repository has been archived by the owner on Feb 3, 2020. It is now read-only.

Softeq/query-utils

Folders and files

NameName
Last commit message
Last commit date

Latest commit

 

History

10 Commits
 
 
 
 
 
 
 
 
 
 
 
 
 
 

Repository files navigation

Azure DevOps builds NuGet

Query Utils

Query Utils is extension for IQueryable to perform Paging, Filer and Sorting operations

Usage

Query Utils extension currently supports the following types of data manipulations, which you may implement in your query:

  • IPagedQuery (allows you to get a sample of data splitted by pages)
  • IFilteredQuery (allows to set collection of filters in request)
  • ISortedQuery (allows ASC/DESC ordering response data by definite property)
public class UserProfile
{
    [JsonProperty("id")]
    public Guid Id { get; set; }

    [JsonProperty("firstName")]
    public string FirstName { get; set; }
}

Query implementation:

public class GetProfilesQuery : IPagedQuery, IFilteredQuery, ISortedQuery
{
	public int Page { get; set; } = 1;
	public int PageSize { get; set; } = 20;
	public ICollection<Filter> Filters { get; set; }
	public Sort Sort { get; set; }
}

Implement the following extension method for filtering:

public static IEnumerable<Func<IQueryable<UserProfile>, IQueryable<UserProfile>>> CreateFilters(this GetProfilesQuery query)
{
    var filters = new List<Func<IQueryable<UserProfile>, IQueryable<UserProfile>>>();
    var map = typeof(UserProfile).GetProperties()
            .Where(x => x.GetCustomAttribute<JsonPropertyAttribute>() != null)
            .ToLookup(x => x.GetCustomAttribute<JsonPropertyAttribute>().PropertyName);

    if (query.Filters != null)
    {
        foreach (var filter in query.Filters)
        {
            var property = map[filter.PropertyName].FirstOrDefault();
            if (property == null)
            {
                throw new QueryException($"Could not find '{filter.PropertyName}' in model scheme.");
            }

            switch (property.Name)
            {
                case nameof(UserProfile.FirstName):
                {
                    filters.Add(x => x.Where(e => e.FirstName.Contains(filter.Value)));
                    break;
                }
...
             }
         }
     }

     return filters;
}

Implement the following extension method for sorting:

public static Func<IQueryable<UserProfile>, IQueryable<UserProfile>> CreateOrdering(this GetProfilesQuery query)
{
    Func<IQueryable<UserProfile>, IQueryable<UserProfile>> order = null;

    if (query.Sort != null)
    {
        var map = typeof(UserProfile).GetProperties()
               .Where(x => x.GetCustomAttribute<JsonPropertyAttribute>() != null)
               .ToLookup(x => x.GetCustomAttribute<JsonPropertyAttribute>().PropertyName);

        var property = map[query.Sort.PropertyName].FirstOrDefault();
        if (property == null)
        {
            throw new QueryException($"Could not find '{query.Sort.PropertyName}' in model scheme.");
        }

        Expression<Func<UserProfile, object>> sortExpression;

        switch (property.Name)
        {
            case nameof(UserProfile.FirstName):
            {
                sortExpression = x => x.FirstName;
                break;
            }
...
        }

        order = query.Sort.Order == SortOrder.Asc 
              ? (Func<IQueryable<UserProfile>, IQueryable<UserProfile>>) (x => x.OrderBy(sortExpression))
              : (x => x.OrderByDescending(sortExpression));
    }

    return order;
}

Usage example:

var filters = request.Query.CreateFilters();
var ordering = request.Query.CreateOrdering();

var filteredProfiles = new QuerySpecification<UserProfile>()
	.WithFilters(filters)
	.WithOrdering(ordering)
	.ApplyFiltering(profiles);

return PageUtil.CreatePagedResults(filteredProfiles, request.Query.Page, request.Query.PageSize, Mapper.Map<UserProfile, ProfileResponse>);

About

This project is maintained by Softeq Development Corp. We specialize in .NET core applications.

Contributing

We welcome any contributions.

License

The Query Utils project is available for free use, as described by the LICENSE (MIT).

Releases

No releases published

Packages

No packages published

Languages