Git Product home page Git Product logo

odata.querybuilder's Introduction

OData.QueryBuilder

Library for creating complex OData queries (OData version 4.01) based on data models with linq syntax.

Build Status Coverage Status Nuget Status

Benefits

Installation

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

To add a link to the main dotnet project, run the following command line:

dotnet add package OData.QueryBuilder

Usage

  1. Build instance

    As soon as possible, create a new instance of the OData.QueryBuilder object indicating the data models and the optional base path:

    var odataQueryBuilder = new ODataQueryBuilder<Your OData root model>(<Your base url>?);
    
    // specify the resource for which the request will be built
    odataQueryBuilder.For<Your OData entity model>(s => s.ODataEntity)

    ℹ️ OData.Query Builder assumes you are using OData Connected Service and you have a root model otherwise use:

    var odataQueryBuilder = new ODataQueryBuilder(<Your base url>?);
    
    // specify the resource for which the request will be built
    odataQueryBuilder.For<Your OData entity model>("ODataEntity")
  2. Select request type

    The builder allows you to build queries on the key and the list:

  3. Get Uri request or collection of operators from the builder

    odataQueryBuilder.ToUri()
    odataQueryBuilder.ToDictionary()

Fluent api

var uri = new ODataQueryBuilder<ODataInfoContainer>("http://mock/odata")
    .For<ODataTypeEntity>(s => s.ODataType)
    .ByKey(223123123)
    .ToUri()

http://mock/odata/ODataType(223123123)

var uri = new ODataQueryBuilder<ODataInfoContainer>("http://mock/odata")
    .For<ODataTypeEntity>(s => s.ODataType)
    .ByKey("223123123")
    .ToUri()

http://mock/odata/ODataType("223123123")

var uri = new ODataQueryBuilder<ODataInfoContainer>("http://mock/odata")
    .For<ODataTypeEntity>(s => s.ODataType)
    .ByKey(223123123)
    .For<ODataKindEntity>(s => s.ODataKind)
    .ByKey(223123123)
    .ToUri()

http://mock/odata/ODataType(223123123)/ODataKind(223123123)

var uri = new ODataQueryBuilder<ODataInfoContainer>("http://mock/odata")
    .For<ODataTypeEntity>(s => s.ODataType)
    .ByList()
    .ToUri()

http://mock/odata/ODataType

Usage options

.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 || s.ODataKind.OpenDate == new DateTime(2019, 7, 9)) || 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

ℹ️ Use parenthesis in filter

var constStrIds = new[] { "123", "512" };
var constValue = 3;
...
.Filter((s, f, o) => s.IdRule == constValue
    && s.IsActive
    && (f.Date(s.EndDate.Value) == default(DateTimeOffset?) || s.EndDate > DateTime.Today)
    && (f.Date((DateTimeOffset)s.BeginDate) != default(DateTime?) || f.Date((DateTime)s.BeginDate) <= DateTime.Now)
    && o.In(s.ODataKind.ODataCode.Code, constStrIds), useParenthesis: true)

$filter=(((IdRule eq 3 and IsActive) and (date(EndDate) eq null or EndDate gt 2020-08-29T00:00:00Z)) and (date(BeginDate) ne null or date(BeginDate) le 2020-08-29T18:09:15Z)) and ODataKind/ODataCode/Code in ('123','512')

.OrderBy(s => s.IdType)

$orderby=IdType asc

.OrderBy(s => new { s.IdType, s.Sum })

$orderby=IdType,Sum asc

.OrderBy((entity, sort) => sort
    .Ascending(entity.BeginDate)
    .Descending(entity.EndDate)
    .Ascending(entity.IdRule)
    .Ascending(entity.Sum)
    .Descending(entity.ODataKind.OpenDate))

$orderby=BeginDate asc,EndDate desc,IdRule asc,Sum asc,ODataKind/OpenDate desc

.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

Usage operators

.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)

Usage date functions

.Filter((s, f) => f.Date(s.Open) == DateTime.Today)

$filter=date(Open) eq 2019-02-09T00:00:00Z

Usage string and collections functions

.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) => f.IndexOf(s.ODataKind.ODataCode.Code, "testCode") == 1)

$filter=indexof(ODataKind/ODataCode/Code,'testCode') eq 1

.Filter((s, f) => f.StartsWith(s.ODataKind.ODataCode.Code, "test"))

$filter=startswith(ODataKind/ODataCode/Code,'test')

Usage other functions

ConvertEnumToString

.Filter((s, f) => s.ODataKind.Color == f.ConvertEnumToString(ColorEnum.Blue))

$filter=ODataKind/Color eq 'Blue'

ConvertDateTimeToString

.Filter((s, f) => s.ODataKind.OpenDate == f.ConvertDateTimeToString(new DateTime(2019, 2, 9), "yyyy-MM-dd"))

$filter=ODataKind/OpenDate eq 2019-02-09

ConvertDateTimeOffsetToString

.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

ReplaceCharacters

var dictionary = new Dictionary<string, string> { { "&", "%26" } });
var constValue = "3 & 4";
...
.Filter((s, f) => s.ODataKind.ODataCode.Code == f.ReplaceCharacters(
    constValue,
    dictionary)

$filter=ODataKind/ODataCode/Code eq '3 %26 4'

var strings = new string[] {
    "test\\YUYYUT",
    "test1\\YUYY123"
};
...
.Filter((s, f, o) => o.In(s.ODataKind.ODataCode.Code, f.ReplaceCharacters(
    strings,
    new Dictionary<string, string>() { { @"\", "%5C" } })))

$filter=ODataKind/ODataCode/Code in ('test%5C%5CYUYYUT','test1%5C%5CYUYY123')

Suppress exceptions

⚠️ May result in loss of control over the expected result.

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]) || 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)

odata.querybuilder's People

Contributors

alexandresanlim avatar h3rmanj avatar zexsm avatar

Recommend Projects

  • React photo React

    A declarative, efficient, and flexible JavaScript library for building user interfaces.

  • Vue.js photo Vue.js

    🖖 Vue.js is a progressive, incrementally-adoptable JavaScript framework for building UI on the web.

  • Typescript photo Typescript

    TypeScript is a superset of JavaScript that compiles to clean JavaScript output.

  • TensorFlow photo TensorFlow

    An Open Source Machine Learning Framework for Everyone

  • Django photo Django

    The Web framework for perfectionists with deadlines.

  • D3 photo D3

    Bring data to life with SVG, Canvas and HTML. 📊📈🎉

Recommend Topics

  • javascript

    JavaScript (JS) is a lightweight interpreted programming language with first-class functions.

  • web

    Some thing interesting about web. New door for the world.

  • server

    A server is a program made to process requests and deliver data to clients.

  • Machine learning

    Machine learning is a way of modeling and interpreting data that allows a piece of software to respond intelligently.

  • Game

    Some thing interesting about game, make everyone happy.

Recommend Org

  • Facebook photo Facebook

    We are working to build community through open source technology. NB: members must have two-factor auth.

  • Microsoft photo Microsoft

    Open source projects and samples from Microsoft.

  • Google photo Google

    Google ❤️ Open Source for everyone.

  • D3 photo D3

    Data-Driven Documents codes.