Easily Query Data Over Service Boundaries

SERVICE QUERY is an expression builder that serializes query instructions over service boundaries. It dynamically builds queries with support for many popular relational and NoSQL database engines.

Coming Soon!


Currently in Beta. We plan to release Q4 of 2022

Features

1

Simple Object Model

Serialize our simple object model to achieve complex query expressions.

2

IQueryable and Expressions

Use IQueryable or expression functions to dynamically build your queries.

3

Multiple Database Engines

We support several relational and non-relational (NoSQL) database engines.

4

Entity Framework Core

Additional library with integration and support for asynchronous methods.

Roadmap

How It Works

Easier Access to your Data

When building APIs, developers typically have to create several API methods to expose their data. For example, one API method may return a list of items based on a passed in variable, like an identifier or a primary key. Another method may gets items that are in a category based on a passed in name. And so on...

The reason is because there is not an easy way for developers to serialize complex queries over service APIs that supports multiple backend storage providers. SERVICE QUERY provides several solutions to solve this problem.

  • An expression builder that allows building complex queries that can be use for all supported storage platforms
  • A simplified object model that can be serialized over service API methods and allows quick mapping and translations
  • A dynamic query builder used with IQuerable, Expressions, Functions, or provider specific methods for querying using their interfaces

Getting Started

View Examples and Defect Tracking at
GitHub logo GitHub text

Get It At
NuGet logo
Latest Version
1.0.1
Development Status

Beta Testing

FREE Evaluation

SERVICE QUERY is paid software and requires a license key to work correctly. You can evaluate our software, however it will throw exceptions after 30 minutes of use. Using a valid license key disables this impairment.

Installation

The NuGet package name is "ServiceQuery" Install the library by using the following command:

Using .NET CLI

dotnet add package ServiceQuery

Using Package Manager
NuGet package manager servicequery

Entity Framework Core Async() Support

Support for EFCore's asynchronous methods are handled by installing the following library:


dotnet add package ServiceQuery.EntityFrameworkCore

Using Package Manager
NuGet package manager servicequery.entityframeworkcore

How To Use

Looking for Complete Examples?
https://github.com/holomodular/ServiceQuery

Visit our GitHub page for:

  • Examples
  • Community Contributions
  • Defect Tracking
  • Downloadable Documentation
Supported Storage Providers
Azure Data Tables logo
Azure Data Tables
Azure SQL logo
Azure SQL
Cosmos DB logo
Azure Cosmos DB
Cosmos DB logo
Microsoft SQL Server
Cosmos DB logo
MongoDB
.NET Core logo
.NET Core
PostgreSQL logo
PostgreSQL
PostgreSQL logo
SqLite

1

Create an API method to use SERVICE QUERY


using ServiceQuery;

// This is only needed if using EntityFrameworkCore and async() methods
//using ServiceQuery.EntityFrameworkCore;

[HttpPost]
[Route("Query")]
public List<MyEntityObject> Query([FromBody] ServiceQuery.Query query)
{
	var queryableObject = _dbContext.Set<MyEntityObject>().AsQueryable();
	queryableObject = query.GetQueryable(queryableObject);

	// If using EntityFrameworkCore and async() methods, use this instead
	//queryableObject = query.GetQueryableEntityFrameworkCore(queryableObject);

	var list = queryableObject.ToList();

	// If using automapper, map to your Dto type and return
	// return _mapper.Map<List<MyEntityDto>>(list);

	return list;
}

2

Build a Query, Call the Method and Get Data


using ServiceQuery;

public void CallQuery()
{
	// Build a query that is serializable 
	// Same as: .Where(x=> x.MessageText == "Hello World")
	var query = QueryBuilder.New()
		.IsEqual("MessageText", "Hello World")
		.Build();

	var resultList = _clientController.Query(query);	
}

SERVICE QUERY also works with data stored in a System.Collection.List!

Query Expressions

Not all expressions are available for every storage provider. View our GitHub documentation to learn more.

Comparisons

						
		// 

Equals

// Where(x=> x.FirstName == "Bob") var query = QueryBuilder.New() .IsEqual("FirstName", "Bob") .Build(); //

Not Equals

// Where(x=> x.FirstName != "Bob") var query = QueryBuilder.New() .IsNotEqual("FirstName", "Bob") .Build(); //

Greater Than

// Where(x=> x.Age > 18) var query = QueryBuilder.New() .IsGreaterThan("Age", "18") .Build(); //

Greater Than or Equal

// Where(x=> x.Age >= 18) var query = QueryBuilder.New() .IsGreaterThanOrEqual("Age", "18") .Build(); //

Less Than

// Where(x=> x.Age < 60) var query = QueryBuilder.New() .IsLessThan("Age", "60") .Build(); //

Less Than or Equal

// Where(x=> x.Age <= 60) var query = QueryBuilder.New() .IsLessThanOrEqual("Age", "60") .Build(); // Contains // Where(x=> x.FirstName.Contains("Bo")) var query = QueryBuilder.New() .Contains("FirstName", "Bo") .Build(); //

Starts With

// Where(x=> x.FirstName.StartsWith("Bo")) var query = QueryBuilder.New() .StartsWith("FirstName", "Bo") .Build(); //

Ends With

// Where(x=> x.FirstName.EndsWith("ob")) var query = QueryBuilder.New() .EndsWith("FirstName", "ob") .Build(); //

Is Null (Not available for all providers)

// Where(x=> x.MiddleName == null) var query = QueryBuilder.New() .IsNull("MiddleName") .Build(); //

Is Not Null (Not available for all providers)

// Where(x=> x.MiddleName != null) var query = QueryBuilder.New() .IsNotNull("MiddleName") .Build(); //

Between

// Where(x=> x.Age >= 18 && x.Age <= 60) var query = QueryBuilder.New() .Between("Age","18","60") .Build(); //

Is In Set

// var ageList = new List<int>(){ 18, 30, 40, 50 }; // Where(x=> ageList.Contains(x.Age)) var query = QueryBuilder.New() .IsInSet("Age","18","30","40", "50") .Build(); //

Is Not In Set

// var ageList = new List<int>(){ 18, 30, 40, 50 }; // Where(x=> !ageList.Contains(x.Age)) var query = QueryBuilder.New() .IsNotInSet("Age","18","30","40", "50") .Build();

Grouping Expressions

						
		// 

And

// Where(x=> x.FirstName == "Bob" && x.Age > 18) var query = QueryBuilder.New() .IsEqual("FirstName", "Bob") .And() .IsGreaterThan("Age", "18") .Build(); // SERVICE QUERY will automatically add an AND() expression if one is expected // Where(x=> x.FirstName == "Bob" && x.Age > 18) var query = QueryBuilder.New() .IsEqual("FirstName", "Bob") //.And() .IsGreaterThan("Age", "18") .Build(); //

Or

// Where(x=> x.FirstName == "Bob" || x.Age > 18) var query = QueryBuilder.New() .IsEqual("FirstName", "Bob") .Or() .IsGreaterThan("Age", "18") .Build(); //

Begin and End Expressions

// Where(x=> (x.FirstName == "Bob" && x.Age > 18) || // (x.FirstName == "John" && x.Age < 60) ) var query = QueryBuilder.New() .BeginExpression() .IsEqual("FirstName", "Bob") .And() .IsGreaterThan("Age", "18") .EndExpression() .Or() .BeginExpression() .IsEqual("FirstName", "John") .And() .IsLessThan("Age", "60") .EndExpression() .Build();

Aggregate and Special


		// 

Distinct

// queryable.Distinct() var query = QueryBuilder.New() .Distinct() .Build(); // Count() // query.Count() var query = QueryBuilder.New() .Count() .Build(); //

Average

// queryable.Average(x=> x.Age) var query = QueryBuilder.New() .Average("Age") .Build(); // Minimum // queryable.Minimum(x=> x.Age) var query = QueryBuilder.New() .Minimum("Age") .Build(); // Maximum // queryable.Maximum(x=> x.Age) var query = QueryBuilder.New() .Maximum("Age") .Build();

Select and Sort


		// 

Select

// queryable.Select(x=> new{ FirstName = x.FirstName, LastName = x.LastName}) var query = QueryBuilder.New() .Select("FirstName", "LastName") .Build(); //

Sort

// queryable.Sort(x=> x.Age) var query = QueryBuilder.New() .Sort("Age", true) .Build();

Contact Us

How can we help you?

Our goal is to help our customers become successful with our products. Please let us know how we can help.

Jacksonville, Florida, USA

9am to 5pm EST