Dekiru.QueryFilter 2.3.0

Prefix Reserved
There is a newer version of this package available.
See the version list below for details.
dotnet add package Dekiru.QueryFilter --version 2.3.0                
NuGet\Install-Package Dekiru.QueryFilter -Version 2.3.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="Dekiru.QueryFilter" Version="2.3.0" />                
For projects that support PackageReference, copy this XML node into the project file to reference the package.
paket add Dekiru.QueryFilter --version 2.3.0                
#r "nuget: Dekiru.QueryFilter, 2.3.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 Dekiru.QueryFilter as a Cake Addin
#addin nuget:?package=Dekiru.QueryFilter&version=2.3.0

// Install Dekiru.QueryFilter as a Cake Tool
#tool nuget:?package=Dekiru.QueryFilter&version=2.3.0                

Dynamic query filter parser

This library provides a parser for a simple query language that can be used to filter data in the form of IQueryable<T>. The main use case is to provide a simple query language for REST APIs to use with Entity Framework Core. The library is inspired by the OData query language, but only a subset of the OData query language is supported (i.e., $filter, $orderby, and $expand).

The library is available as a NuGet package: Dekiru.QueryFilter.

The two main methods are FilterDynamic and IncludeDynamic which can be used to filter and include related entities respectively. The methods are defined as extension methods on IQueryable<T>.

The methods take a string as input which is parsed and converted to an expression tree. The expression tree is then used to filter the data or define the related entities to include. The included entities may also be filtered.

Generally, all methods can be called either as a static method or as a member method. The syntax is either myMethod(SomeCollection) or SomeCollection.myMethod(). There is no functional difference between the two syntaxes, it is just a matter of preference.

Some methods may be called with a predicate, they are defined as a lamba expression:

SomeCollection.myMethod(c: c.Name eq 'John')

Nested predicates are supported:

SomeCollection.myMethod(c: c.OtherProp.Count(r: r.Name eq 'Bar') gt 5)

There is a special meta variable called $, that can be used to refer to the Entity Framework Core DbContext instance. This can be used to filter on entities that are not connected to the entity that is being queried.

Note: Null semantics, as well as case sensitivity, are determined by the underlying data source.

Operators

The following infix/prefix operators are supported:

  • and - SQL AND operator
  • or - SQL OR operator
  • not - SQL NOT operator
  • eq - SQL = operator
  • ne - SQL <> operator
  • gt - SQL > operator
  • ge - SQL >= operator
  • lt - SQL < operator
  • le - SQL <= operator

Functions

  • any() - Returns true if the collection contains any entries: Items.any()
  • any(predicate) - Returns true if the collection contains any entries that match the predicate: Items.any(i: i.Name eq "Foo")
  • all(predicate) - Returns true if all of the entries in the collection matches the predicate: Items.all(i: i.Name eq "Foo")
  • startsWith(match) - Returns true if the string starts with the given value: Name.startsWith("foo")
  • endsWith(match) - Returns true if the string ends with the given value: Name.endsWith("foo")
  • substring(start) - Extracts characters to the end of a string, beginning at start: Name.substring(1)
  • substring(start, length) - Extracts length characters from a string, beginning at start: Name.substring(1, 5)
  • datepart(datePart) - Extracts a part of a date: SomeDate.datepart("day")
  • dateadd(datePart, value) - Increments or decrements a date: SomeDate.dateadd("day", 1)
  • tostring() - Converts a value to a string: SomeNumber.toString()
  • trim() - Removes leading and trailing whitespace from a string: Name.trim()
  • length() - Example: Name.length()
  • contains(arg) - Example: name.Contains("foo")
  • count() - Returns the number of entries in the collection: Items.count()
  • count(predicate) - Returns the number of entries in the collection that matches the predicate: Items.count(i: i.Name eq "Foo")
  • sum(selector) - Returns the sum of a property in all entries in the collection: Items.sum(i: i.SomeNumber)
  • max(selector) - Returns the maximum value of a property in the collection: Items.max(i: i.SomeNumber)
  • coalesce(alternative) - Returns the value of the property if it is not null, otherwise the supplied value will be returned: Name.coalesce("bar")
  • empty() - Returns true if the property is an empty string: Name.empty()
  • isnull() - Returns true if the property is null: Name.isnull()
  • lower() - Converts a string to lower case: Name.lower()
  • upper() - Converts a string to upper case: Name.upper()
  • now() - Returns a DateTime object representing the current date and time: now()
  • utcNow() - Returns a DateTime object representing the current date and time in UTC: utcNow()
  • long() - Converts a value to a long: SomeProp.long()
  • ulong() - Converts a value to an unsigned long: SomeProp.ulong()
  • int() - Converts a value to an int: SomeProp.int()
  • uint() - Converts a value to an int: SomeProp.uint()
  • short() - Converts a value to a short: SomeProp.short()
  • ushort() - Converts a value to an ushort: SomeProp.ushort()
  • byte() - Converts a value to a byte: SomeProp.byte()
  • sbyte() - Converts a value to an sbyte: SomeProp.sbyte()
  • decimal() - Converts a value to a decimal: SomeProp.decimal()
  • double() - Converts a value to an double: SomeProp.double()
  • float() - Converts a value to an float: SomeProp.float()
  • bool() - Converts a value to an bool: SomeProp.bool()

Function names are case insensitive.

Sample queries

Name eq 'John' and not Name eq 'Doe'
Name eq 'John' and Age gt 30
Name eq 'John' or Age gt 30
Name eq 'John' and (Age gt 30 or Age lt 20)

Children.any()

Children.any(c: c.Name eq 'Bar')

Children.count() gt 0

Children.count(c: c.Name eq 'Bar') gt 0

Children.all(c: c.Name eq 'Bar')

Children.count(c: c.Relatives.any(r: r.Name eq 'Bar')) gt 0

Address.Country eq 'Sweden'

Name.startswith('J')

Name.endswith('n')
Product Compatible and additional computed target framework versions.
.NET net6.0 is compatible.  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 is compatible.  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 is compatible.  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.  net9.0 was computed.  net9.0-android was computed.  net9.0-browser was computed.  net9.0-ios was computed.  net9.0-maccatalyst was computed.  net9.0-macos was computed.  net9.0-tvos was computed.  net9.0-windows was computed. 
Compatible target framework(s)
Included target framework(s) (in package)
Learn more about Target Frameworks and .NET Standard.

NuGet packages (1)

Showing the top 1 NuGet packages that depend on Dekiru.QueryFilter:

Package Downloads
Dekiru.Internals.ApiUtils

Package Description

GitHub repositories

This package is not used by any popular GitHub repositories.

Version Downloads Last updated
9.4.6 83 1/24/2025
9.4.5 83 1/23/2025
9.4.4 261 12/13/2024
9.4.3 119 12/5/2024
9.4.2 104 12/2/2024
9.4.1 138 11/18/2024
9.4.0 96 11/15/2024
9.3.2 104 11/13/2024
9.3.1 98 11/13/2024
8.3.2 120 11/13/2024
8.3.1 95 11/13/2024
8.3.0 125 11/1/2024
8.2.0 144 10/10/2024
8.1.12 139 10/3/2024
8.1.11 113 10/1/2024
8.1.10 101 10/1/2024
8.1.9 198 9/17/2024
8.1.8 123 9/17/2024
8.1.7 133 9/3/2024
8.1.6 121 8/30/2024
8.1.5 504 8/13/2024
6.1.12 99 10/3/2024
6.1.11 96 10/1/2024
6.1.10 96 10/1/2024
6.1.9 136 9/17/2024
6.1.8 118 9/17/2024
6.1.7 107 9/3/2024
6.1.6 105 8/30/2024
6.1.5 136 8/13/2024
6.1.4 117 8/13/2024
3.1.4 87 8/3/2024
3.1.3 195 7/1/2024
3.1.2 106 7/1/2024
3.1.1 116 7/1/2024
3.1.0 138 6/28/2024
3.0.6 138 6/14/2024
3.0.4 164 5/23/2024
3.0.3 129 5/10/2024
3.0.2 100 5/3/2024
3.0.1 143 4/30/2024
3.0.0 132 4/26/2024
2.6.5 121 4/25/2024
2.6.4 130 4/25/2024
2.6.3 122 4/24/2024
2.6.2 124 4/22/2024
2.6.1 158 4/16/2024
2.6.0 131 4/15/2024
2.5.4 148 3/29/2024
2.5.3 123 3/28/2024
2.5.2 127 3/27/2024
2.5.1 131 3/27/2024
2.5.0 124 3/20/2024
2.4.0 128 3/15/2024
2.3.0 117 2/29/2024
2.2.1 129 2/21/2024
2.1.0 144 1/29/2024
2.0.9 133 1/17/2024
2.0.8 125 1/16/2024
2.0.5 128 1/12/2024
2.0.3 175 12/20/2023
2.0.2 127 12/20/2023
2.0.1 138 12/19/2023
2.0.0 144 12/19/2023
1.0.0 200 3/4/2023