Skip to main content

Queries

Overview​

OOQL (Object-Oriented Query Language) is a domain-specific language designed for querying objects in a structured manner. It provides constructs to perform complex queries on objects and their properties, and also allows for grouping, negation, and sub-querying.

The are two Forms of OOQL:

  1. Textual Form: This is a string representation, similar to traditional SQL. It allows expressing conditions, operators, and references in a textual manner.
  2. Typed/Formal Form: This is more oriented towards .NET code and involves the usage of classes, objects, and methods to construct the query.

Textual Form​

Where Expression​

A whereExpression is the core of any OOQL query. It's composed of one of the following:

  • A groupExpression
  • A subQueryExpression
  • A negateExpression

Group Expression​

A groupExpression is composed of multiple andGroupExpression combined using the OR operator. This facilitates the logical 'AND' and 'OR' operations within queries.

Comparison Expression​

A comparisonExpression represents the most basic form of filtering in the OOQL, comparing a variable operand or identifier against another operand using a comparison operator.

Negate Expression​

Negates the result of a whereExpression.

Sub-Query Expression​

Allows for a nested whereExpression, enabling hierarchical querying.

Using Expression​

Represents the USING keyword, useful for querying with specific parameters or conditions.

Reference Expression​

Denotes the REFERENCE keyword, likely to retrieve or specify certain object references.

Operators​

  • Logical Operators: AND, OR
  • Comparison Operators: EQUAL, NOTEQUAL, LT, LTEQ, GT, GTEQ, LIKE, CONTAINS, NOTCONTAINS
  • Special Operators: NEGATEOPERATOR, SUBQUERYOPERATOR, USINGOPERATOR, REFERENCEOPERATOR

Operands​

  • Variable Operand: Represents an object's property or a chain of properties (like object.property1.property2).
  • Right Expression Operand: Can be either a scalarExpressionOperand or a referenceExpressionOperand.
  • Scalar Expression Operand: Represents primitive data types including integers, floats, dates, booleans, and strings.

Data Types​

  • INTEGER: Whole numbers.
  • FLOAT: Decimal numbers.
  • DATETIME: Date and time values enclosed in #.
  • BOOLEAN: Represents true or false.
  • STRING: Text enclosed in single quotes (').

Sample Queries​

  1. Basic comparison:

    object.property = 10
  2. Using negation:

    NOT(object.property = 'sample')
  3. Sub-query:

    object IN (anotherObject.property = 'value')
  4. Grouping:

    (object.property1 = 'value1' AND object.property2 = 'value2') OR object.property3 = 'value3'
  5. Using the USING keyword:

    USING 'sampleParameter'

Typed/Formal Form​

1. WhereExpression​

  • Represents a condition in the query.
  • Base class for other conditional expressions.

2. WhereOperand​

  • Represents a value or a reference in a condition.
  • Can be a scalar value, field, or reference.

3. WhereOperator​

  • Enumerates the different comparison operations, e.g., Equal, NotEqual, GreaterThan, etc.

4. WhereLogicator​

  • Enumerates logical operations used to combine conditions, e.g., And, Or.

Basic Usage​

Query Construction​

  1. Field Selection:

    • Extract fields using DataItemClassInfo based on the data type.

      var firstNameField = DataItemClassInfo.GetClassInfo(typeof(Person)).GetField(nameof(Person.FirstName));
  2. Condition Creation:

    • Use the extracted fields to create conditional expressions.

      var firstNameCondition = new WhereComparisonExpression(firstNameField, WhereOperator.Equal, new WhereScalarOperand("John"));
  3. Combining Conditions:

    • Combine multiple conditions using the WhereGroupExpression.

      var finalQuery = new WhereGroupExpression(WhereLogicator.And, firstNameCondition, lastNameCondition);

Advanced Usage​

Sub-Queries​

  • Utilize WhereSubQueryExpression to represent sub-queries.

    var subQueryCondition = new WhereComparisonExpression(authorCountryField, WhereOperator.Equal, new WhereScalarOperand("UK"));
    var finalQuery = new WhereSubQueryExpression(bookAuthorField, subQueryCondition);

Negations​

  • Use the WhereNegateExpression for negating conditions.

    var finalQuery = new WhereNegateExpression(categoryCondition);

Object Relationships​

  • Queries can span across related objects.

    var productCategoryField = DataItemClassInfo.GetClassInfo(typeof(OrderLines)).GetField(nameof(OrderLines.Product.Category));

The typed/formal form of OOQL gives developers the power to leverage their coding skills for constructing queries. It ensures type-safety and clarity, making it a robust choice for object-oriented data model querying.

Examples​

1. Basic Query​

Textual Form:

FirstName = 'John' AND LastName = 'Doe'

Typed/Formal Form (C#):

var firstNameField = DataItemClassInfo.GetClassInfo(typeof(Person)).GetField(nameof(Person.FirstName));
var lastNameField = DataItemClassInfo.GetClassInfo(typeof(Person)).GetField(nameof(Person.LastName));

var firstNameCondition = new WhereComparisonExpression(firstNameField, WhereOperator.Equal, new WhereScalarOperand("John"));
var lastNameCondition = new WhereComparisonExpression(lastNameField, WhereOperator.Equal, new WhereScalarOperand("Doe"));

var finalQuery = new WhereGroupExpression(WhereLogicator.And, firstNameCondition, lastNameCondition);

2. Using References:​

Textual Form:

Customer.Reference = 'C12345'

Typed/Formal Form (C#):

var customerReferenceField = DataItemClassInfo.GetClassInfo(typeof(Invoice)).GetField(nameof(Invoice.Customer.Reference));

var referenceCondition = new WhereComparisonExpression(customerReferenceField, WhereOperator.Equal, new WhereScalarOperand("C12345"));

var finalQuery = referenceCondition;

3. Using Sub-Queries​

Textual Form:

Book.Author IN (Author.Country = 'UK')

Typed/Formal Form (C#):

var authorCountryField = DataItemClassInfo.GetClassInfo(typeof(Author)).GetField(nameof(Author.Country));
var bookAuthorField = DataItemClassInfo.GetClassInfo(typeof(Book)).GetField(nameof(Book.Author));

var subQueryCondition = new WhereComparisonExpression(authorCountryField, WhereOperator.Equal, new WhereScalarOperand("UK"));

var finalQuery = new WhereSubQueryExpression(bookAuthorField, subQueryCondition);

4. Negation​

Textual Form:

NOT Product.Category = 'Electronics'

Typed/Formal Form (C#):

var categoryField = DataItemClassInfo.GetClassInfo(typeof(Product)).GetField(nameof(Product.Category));

var categoryCondition = new WhereComparisonExpression(categoryField, WhereOperator.Equal, new WhereScalarOperand("Electronics"));

var finalQuery = new WhereNegateExpression(categoryCondition);

5. Using Object Relationships:​

Textual Form:

Order.OrderDate > '01-01-2023' AND OrderLines.Product.Category = 'Books'

Typed/Formal Form (C#):

var orderDateField = DataItemClassInfo.GetClassInfo(typeof(Order)).GetField(nameof(Order.OrderDate));
var productCategoryField = DataItemClassInfo.GetClassInfo(typeof(OrderLines)).GetField(nameof(OrderLines.Product.Category));

var dateCondition = new WhereComparisonExpression(orderDateField, WhereOperator.GreaterThan, new WhereScalarOperand(new DateTime(2023, 1, 1)));
var categoryCondition = new WhereComparisonExpression(productCategoryField, WhereOperator.Equal, new WhereScalarOperand("Books"));

var finalQuery = new WhereGroupExpression(WhereLogicator.And, dateCondition, categoryCondition);