Library provides linq syntax and allows you to build OData queries based on the data model
- Expression is not used to
Compile()
, which generatesMSIL
code, which leads to memory leaks - Support:
- nested
OData
extenders with a choice of filtering - operators
all
,any
,in
- date functions
date
- string functions
contains
,substringof
,toupper
,tolower
- nested
To install OData.QueryBuilder
from Visual Studio
, find OData.QueryBuilder
in the NuGet
package manager user interface or enter the following command in the package manager console:
Install-Package OData.QueryBuilder -Version 1.0.0
To add a link to the main dotnet project, run the following command line:
dotnet add -v 1.0.0 OData.QueryBuilder
-
Build instance
As soon as possible, create a new instance of the OData.QueryBuilder object indicating the data models and the base path:
var odataQueryBuilder = new ODataQueryBuilder<Your entity model>(<base_url>);
-
Specify the resource for which the request will be built
odataQueryBuilder.For<Your data model>(s => s.<Your resource model>)
-
Select request type
The builder allows you to build queries on the key and the list:
-
Get Uri request or collection of operators from the builder
odataQueryBuilder.ToUri() odataQueryBuilder.ToDictionary()
var uri = new ODataQueryBuilder<ODataInfoContainer>("http://mock/odata")
.For<ODataTypeEntity>(s => s.ODataType)
.ByKey(223123123)
.ToUri()
var uri = new ODataQueryBuilder<ODataInfoContainer>("http://mock/odata")
.For<ODataTypeEntity>(s => s.ODataType)
.ByKey("223123123")
.ToUri()
var uri = new ODataQueryBuilder<ODataInfoContainer>("http://mock/odata")
.For<ODataTypeEntity>(s => s.ODataType)
.ByList()
.ToUri()
.Select(s => s.Id)
$select=Id
.Select(s => new { s.Id, s.Sum, s.Type })
$select=Id,Sum,Type
.Expand(s => s.BaseType)
$expand=BaseType
.Expand(s => new { s.BaseType, s.ODataKind })
$expand=BaseType,ODataKind
.Expand(f => f
.For<ODataKindEntity>(s => s.ODataKind)
.Expand(s=> s
.For<ODataCodeEntity>(s => s.ODataCode)
.Filter(s => s.IdKind == 1)
.OrderBy(s => s.IdKind)
.Top(1)
.Select(s => s.IdCode));
})
$expand=ODataKind($expand=ODataCode($filter=IdKind eq 1;$orderby=IdKind;$top=1;$select=IdCode))
.Filter(s => s.ODataKind.ODataCode.Code >= "test_code" || s.IdType >= 5)
$filter=ODataKind/ODataCode/IdCode eq 'test_code' or IdType ge 5
.Filter(s => s.IdRule != default(int?) && s.IdRule == null)
$filter=IdRule ne null and IdRule eq null
.Filter(s => s.ODataKind.OpenDate == DateTime.Today or s.ODataKind.OpenDate == new DateTime(2019, 7, 9)) or s.ODataKind.OpenDate == DateTime.Now)
$filter=ODataKind/OpenDate eq 2019-02-09T00:00:00Z or ODataKind/OpenDate eq 2019-02-09T00:00:00Z or ODataKind/OpenDate eq 2019-02-09T15:10:20Z
.Filter(s => s.IsActive && s.IsOpen == true && !s.ODataKind.ODataCode.IdActive)
$filter=IsActive and IsOpen eq true and not ODataKind/ODataCode/IdActive
.Filter(s => s.ODataKind.Color == ColorEnum.Blue)
$filter=ODataKind/Color eq 2
.OrderBy(s => s.IdType)
$orderby=IdType asc
.OrderBy(s => new { s.IdType, s.Sum })
$orderby=IdType,Sum asc
.OrderByDescending(s => s.IdType)
$orderby=IdType desc
.OrderByDescending(s => new { s.IdType, s.Sum })
$orderby=IdType,Sum desc
.Count()
$count=true
.Count(false)
$count=false
.Skip(12)
$skip=12
.Top(100)
$top=100
.Filter((s, f, o) => o.In(s.ODataKind.ODataCode.Code, new[] { "123", "512" }) && o.In(s.IdType, new[] { 123, 512 }))
$filter=ODataKind/ODataCode/Code in ('123','512') and IdType in (123,512)
.Filter((s, f, o) => o.Any(s.ODataKind.ODataCodes, v => v.IdCode == 1)
$filter=ODataKind/ODataCodes/any(v:v/IdCode eq 1)
.Filter((s, f, o) => o.All(s.ODataKind.ODataCodes, v => v.IdActive))
$filter=ODataKind/ODataCodes/all(v:v/IdActive)
.Filter((s, f) => f.Date(s.Open) == DateTime.Today)
$filter=date(Open) eq 2019-02-09T00:00:00Z
.Filter((s, f) => f.Contains(s.ODataKind.ODataCode.Code, "W"))
$filter=contains(ODataKind/ODataCode/Code,'W')
.Filter((s, f) => f.SubstringOf("W", s.ODataKind.ODataCode.Code))
$filter=substringof('W',ODataKind/ODataCode/Code)
.Filter((s, f) => f.ToUpper(s.ODataKind.ODataCode.Code) == "TEST_CODE")
$filter=toupper(ODataKind/ODataCode/Code) eq 'TEST_CODE'
.Filter((s, f) => f.ToLower(s.ODataKind.ODataCode.Code) == "test_code")
$filter=tolower(ODataKind/ODataCode/Code) eq 'test_code'
.Filter((s, f) => f.Concat(s.ODataKind.ODataCode.Code, "_1") == "test_code_1")
$filter=concat(ODataKind/ODataCode/Code, '_1') eq 'test_code_1'
.Filter((s, f) => s.ODataKind.Color == f.ConvertEnumToString(ColorEnum.Blue))
$filter=ODataKind/Color eq 'Blue'
.Filter((s, f) => s.ODataKind.OpenDate == f.ConvertDateTimeToString(new DateTime(2019, 2, 9), "yyyy-MM-dd"))
$filter=ODataKind/OpenDate eq 2019-02-09
.Filter((s, f) => s.ODataKind.OpenDate == f.ConvertDateTimeToString(new DateTimeOffset(new DateTime(2019, 2, 9)), "yyyy-MM-dd"))
$filter=ODataKind/OpenDate eq 2019-02-09
Suppression of inclusion excludes the whole expression from the request
By default, suppression of function and operator argument exceptions is disabled. To enable it, you must pass the configuration ODataQueryBuilderOptions
when initializing the builder
with initialization of the SuppressExceptionOfNullOrEmptyFunctionArgs
and SuppressExceptionOfNullOrEmptyOperatorArgs
properties.
var builder = new ODataQueryBuilder<ODataInfoContainer>("http://mock/odata", new ODataQueryBuilderOptions {
SuppressExceptionOfNullOrEmptyFunctionArgs = true,
SuppressExceptionOfNullOrEmptyOperatorArgs = true,
});
var uri = builder
.For<ODataTypeEntity>(s => s.ODataType)
.ByList()
.Filter((s, f, o) => o.In(s.ODataKind.ODataCode.Code, new string[0]) or o.In(s.ODataKind.ODataCode.Code, null)
&& f.Contains(s.ODataKind.ODataCode.Code, default(string))
&& o.In(s.IdType, new[] { 123, 512 }))
.ToUri()
http://mock/odata/ODataType?$filter=IdType in (123,512)