Searching for objects in scripts

Mostly scripts are used to search certain objects on different levels of the system. In ELMA you can search for objects using the Find or FindAll methods of entity managers.

We recommend using the FindAll() method for debugging purposes only. It may cause big performance issues if used for the objects with a large number of items.

Using Filters

The most common and accurate search method is by using filters. You can configure filters for each object in ELMA Designer. To do that, go to ELMA DesignerObjectsObject page – Additional tab:

In the settings of each object’s property, specify if it should participate in search or not:

After you have configured the settings and published them, you can use object filters in scripts:

//Get manager for the Pet object
var manager = EntityManager<Pet>.Instance;

//Create filer for the Pet object
var filter = new PetFilter()
    Age = new EleWise.ELMA.Model.Ranges.Int64Range()
        From = 5
    Kind = new DropDownItem("Cat")

//Get the resulting list of objects according to the filter
var pets = manager.Find(filter);

A filter is a class located in the same namespace as the object class. Its name is formed from the object’s class name and the Filter postfix (e.g. the filter for the Pet class is named PetFilter).

When a filter is used, the search is done according to equality of the value in the filter and in the database, if there are no other specific settings (for example, for an Integer variable you can specify that it should be filtered by range, not equality). In case of a String variable, filtering is done by the substring (regardless of case). Any type of variable can participate in filtering.

You cannot change the filtering settings for system objects. (!).

Using filters in search is rather simple, and allows you to find the required data. However, sometimes you need to search objects by properties that are not included in filtering. Below is the example of how you can do that:

Using LINQ for search by obvious matches

C# provides very useful constructions called lambda expressions. You can use them for search:

var pets = EntityManager<Pet>.Instance.Find(p => p.Owner == context.Contact && p.Name == "Sparky");

In the example, the p => p.Owner == context.Contact && p.Name == "Sparky" expression was used for filtering. According to this expression, you must find all the objects belonging to the Pet type, where Owner property’s value = value of Contact variable from the context AND Name is equal to “Sparky”.

When using lambda expressions, you do not need to bother about filter settings, you can search by any object and by any property of the object.

Lambda expressions have certain limitations.
  • can contain only the AND(&&) or OR (||)logical operators in any combination
  • can only search by equality of variable and value (==). For this expression, we recommend using the object's ID.
  • cannot search by nested properties of objects
  • cannot apply functions to the left operand - the variable

Here are some examples of correct and incorrect expressions:

Correct expressions

EntityManager<Pet>.Instance.Find(p => p.Owner == context.Contact && p.Name == pName) //Here pName is a local String type variable
EntityManager<Pet>.Instance.Find(p => p.Age == 10 || p.Kind == new DropDownItem("Cat")) //Only finite data is compared 

Incorrect expressions

EntityManager<Pet>.Instance.Find(p => p.Age > 10) //You cannot use the “greater than” comparison operator 
EntityManager<Pet>.Instance.Find(p => p.Name == p.Owner.Name) //You cannot place the properties of the same object to the right of a comparison operator
EntityManager<Pet>.Instance.Find(p => p.Owner.Name == "Jack") //You cannot search by nested properties of objects

As you can see, lambda expressions give you more possibilities and yet additional limitations, although you can use them regardless of the object’s setting. If you need a more flexible and advanced search system you can try using the EQL language.

Using ELMA Query Language (EQL) for search

Each filter in the system inherits the base IFilter interface, which contains the Query property. You can create a query in this field using EQL in order to select objects with a rather flexible condition.

//Get manager for the Pet object
var manager = EntityManager<Pet>.Instance;

//Create base filter and fill in the query field
var filter = new Filter()
    Query = "(Kind IS NULL OR Age > 25) AND Owner IN (Name = ’Jack’)"

//Get the resulting list of objects according to the filter 
var pets = manager.Find(filter);

In this example, all the objects of the Pet type for which Kind is either blank OR Age is greater than 25 AND Owner’s Name = ‘Jack’ was searched. Let’s review it step by step.

  • Kind is blank OR Age is greater than 25 – this expression is written as Kind IS NULL OR Age > 25
  • Owner meets the condition that Name equals "Jack"- this expression is written as  Owner IN (Name = Jack)

EQL allows you to make subqueries and perform additional filtration by nested properties

You can use this search method in many ways. EQL queries are very flexible and allow you to search by almost any condition.

See also: