QueryX 1.1.0

There is a newer version of this package available.
See the version list below for details.
dotnet add package QueryX --version 1.1.0                
NuGet\Install-Package QueryX -Version 1.1.0                
This command is intended to be used within the Package Manager Console in Visual Studio, as it uses the NuGet module's version of Install-Package.
<PackageReference Include="QueryX" Version="1.1.0" />                
For projects that support PackageReference, copy this XML node into the project file to reference the package.
paket add QueryX --version 1.1.0                
#r "nuget: QueryX, 1.1.0"                
#r directive can be used in F# Interactive and Polyglot Notebooks. Copy this into the interactive tool or source code of the script to reference the package.
// Install QueryX as a Cake Addin
#addin nuget:?package=QueryX&version=1.1.0

// Install QueryX as a Cake Tool
#tool nuget:?package=QueryX&version=1.1.0                

QueryX

QueryX allows performing filtering, paging and sorting to IQueryable ends using URL query strings.

Installation

Install with nuget:

Install-Package QueryX

Usage

Initially it is necessary to add QueryX to the registered services. In Program.cs:

builder.Services.AddQueryX();

A filter model is needed to define the properties that will be used for filtering, this model could be an specific filter class, a Dto or a Domain model object.

public class Card
{
    public int Id { get; set; }
    public string Title { get; set; }
    public string Description { get; set; }
    public int Priority { get; set; }
    public float EstimatedPoints { get; set; }
    public List<User> Owners { get; set; }
}

By default all properties can be used for filtering and sorting, this could be customized using attributes.

Two classes from QueryX are required for creating filters for the Card example object:

  • QueryBuilder, this class should be injected in controllers or where the queries needs to be created.
  • QueryModel, this class is used for capturing queries from URL query strings, it provides Filter, OrderBy, Offset and Limit properties for this purpose.

Additionally, an entity framework context is required for applying the queries:

[HttpGet]
public IActionResult List([FromQuery] QueryModel queryModel)
{
    var query = _queryBuilder.CreateQuery<Card>(queryModel);
    var result = _context.Set<Card>().ApplyQuery(query).ToList();
    return Ok(result);
}

Filtering

Filtering is made using operators, so a filter is defined this way: propertyName operator value.

It is possible to combine multiple filters using "and" (&) and "or" (|) logical operators:

id>1 & title=-'test' | priority|=1,2

For facilitating writing queries in URL, ; (semicolon) character can be used instead for representing the and logical operator:

id>1 ; title=-'test' | priority|=1,2

Filter grouping

Filters can be also grouped using parentheses to determine how they should be evaluated:

id>1 ; (title=-'test' | priority|=1,2)

Collection filters

It is possible to specify filters for collection properties with the following syntax:

propertyName(childPropertyName operator value)

The above code will use the Enumerable.Any method for applying the conditions.

For using the Enumerable.All method:

propertyName*(childPropertyName operator value)

An example using the Card object would be:

owners(id==1 | name=='user2')

Supported value types

Category Description
Numbers integer, float, real, etc.
String, Char should be wrapped in single quotes
DateTime, Timespan should be wrapped in single quotes
Enums should be wrapped in single quotes
Constants true, false, null

Operators

Operator Description Comment
== Equals operator
!= Not equals
< Less than
Less than or equals
> Greater than
>= Greater than or equals
-=- Contains String type only
=- Starts with String type only
-= Ends with String type only
|= In Allows multiple values

Multiple values are specified this way: 0,1,2 or 'val1','val2','val3' if the values are strings

Case insensitive operator

All operators can be combined with the case insensitive operator (*) for ignoring case when comparing strings:

title ==* 'TeSt VaLuE'

This operator is intended to work only with string properties

Not Operator

The not operator (!) can be applied to any filter, collection filter or group:

!id>1 ; !title=-'test' | !priority|=1,2
id>1 ; !(title=-'test' | priority|=1,2)
!owners(id==1 | name=='user2')

Customize filter model

By default all properties from a filter model can be used for filtering and ordering, but there are some attributes that allows to have control on this

Properties marked wth the QueryIgnoreAttribute attribute will be ignored for filtering and ordering:

[QueryIgnore]
public float EstimatedPoints { get; set; }

Also, with QueryOptionsAttribute attribute some other options could be specified:

[QueryOptions(Operator = OperatorType.Equals, IsSortable = false, 
    ParamsPropertyName = "EstimatedPts", ModelPropertyName = "Estimation")]
public float EstimatedPoints { get; set; }
  • Operator will set the default operator for this property, ignoring the one sent in the query string
  • IsSortable determines if this property is sortable or not, true by default
  • ParamsPropertyName is used for mapping filter names from query string. In this case, in query string will be a filter named EstimatedPts that will be mapped to the EstimatedPoints property
  • ModelPropertyName can be used when the filter model is different than the entity in DbContext and the filter model and the entity model have different property names, especifically, this allows mapping this property to a different one in the entity model. In this example, the value for this property will be used in the Estimation property in the entity model because the IQueryable filter needs to be created using the entity model properties

Sorting and Paging

The OrderBy property in QueryModel object allows specifying ordering.

For ascending order base on property Title:

title

For descending order:

-title

It is possible to combine multiple orderings:

id,-priority,title

Custom filters can not be used for ordering

Custom filters

The CustomFilterAttribute attribute allows changing the default behavior of filters:

[CustomFilter]
public int Priority { get; set; }

Properties marked with this attribute will be excluded as part of the filter, custom code needs to be written for doing something with the filter value after the Query object is created:

[HttpGet]
public IActionResult List([FromQuery] QueryModel queryModel)
{
    var query = _queryBuilder.CreateQuery<Card>(queryModel);
    var queryable = _context.Set<Card>();

    // Applying custom filter
    if (query.TryGetFilter(m => m.Priority, out var filter))
    {
        var filterValue = filter.Values.First();
        queryable = queryable.Where(m => m.Priority == filterValue);
    }

    var result = queryable.ApplyQuery(query).ToList();
    return Ok(result);
}

Query exceptions

By default invalid properties will be ignored for filtering and ordering but it is possible to change this behavior by setting ThrowQueryExceptions to true when registering QueryX:

builder.Services.AddQueryX(o => o.ThrowQueryExceptions = true);

These exceptions will be thrown as appropriate:

  • InvalidFilterPropertyException for filtering errors
  • InvalidOrderingPropertyException for ordering errors
Product Compatible and additional computed target framework versions.
.NET net5.0 was computed.  net5.0-windows was computed.  net6.0 was computed.  net6.0-android was computed.  net6.0-ios was computed.  net6.0-maccatalyst was computed.  net6.0-macos was computed.  net6.0-tvos was computed.  net6.0-windows was computed.  net7.0 was computed.  net7.0-android was computed.  net7.0-ios was computed.  net7.0-maccatalyst was computed.  net7.0-macos was computed.  net7.0-tvos was computed.  net7.0-windows was computed.  net8.0 was computed.  net8.0-android was computed.  net8.0-browser was computed.  net8.0-ios was computed.  net8.0-maccatalyst was computed.  net8.0-macos was computed.  net8.0-tvos was computed.  net8.0-windows was computed. 
.NET Core netcoreapp3.0 was computed.  netcoreapp3.1 was computed. 
.NET Standard netstandard2.1 is compatible. 
MonoAndroid monoandroid was computed. 
MonoMac monomac was computed. 
MonoTouch monotouch was computed. 
Tizen tizen60 was computed. 
Xamarin.iOS xamarinios was computed. 
Xamarin.Mac xamarinmac was computed. 
Xamarin.TVOS xamarintvos was computed. 
Xamarin.WatchOS xamarinwatchos was computed. 
Compatible target framework(s)
Included target framework(s) (in package)
Learn more about Target Frameworks and .NET Standard.

NuGet packages

This package is not used by any NuGet packages.

GitHub repositories

This package is not used by any popular GitHub repositories.

Version Downloads Last updated
2.1.1 1,682 3/25/2024
2.1.0 561 12/7/2023
2.0.0 808 11/11/2023
2.0.0-beta.4 76 11/11/2023
2.0.0-beta.3 147 11/5/2023
2.0.0-beta.2 180 10/28/2023
2.0.0-beta.1 79 10/26/2023
2.0.0-alpha-02 81 10/22/2023
2.0.0-alpha-01 88 10/22/2023
1.2.0 233 9/16/2023
1.1.0 265 9/8/2023
1.0.2 628 5/3/2023
1.0.1 143 4/26/2023
1.0.0 403 10/6/2022
1.0.0-beta-0007 106 10/4/2022
1.0.0-beta-0006 163 9/28/2022
1.0.0-beta-0005 143 9/17/2022
1.0.0-beta-0004 189 9/14/2022
1.0.0-beta-0003 116 9/13/2022
1.0.0-beta-0001 110 9/10/2022
1.0.0-alpha-0002 110 9/9/2022
1.0.0-alpha-0001 108 9/8/2022