Skip to content

Defining Queries

A defining query is a read query that targets the OData service associated with the offline store and retrieves a subset of the endpoint data. Multiple defining queries can be defined for each endpoint.

Defining queries retrieve data from the OData service that is sent to the client, either during initialization of the offline store or during a download.

Defining queries are set up in both the application source code and in the application configuration file (if non-default behaviors are expected). In the source code, use the add() method from OfflineODataProvider class with an instance of the OfflineODataDefiningQuery class constructed with a name, a query, and a flag for whether or not automatically retrieving streams. The example below demonstrates how the defining queries retrieve all information for one event.

/// Expand is needed to create a many-to-many relationship between Event and Feature
/// since there is no referential constraint defined on the relationship.
/// Data sharing should be enabled as all users see the same information
try provider.add(definingQuery: OfflineODataDefiningQuery(name: "Events_10000",
                                                          query: "/Events?$filter=EventID eq 10000L&$expand=Features",
                                                          automaticallyRetrievesStreams: false))

/// One-to-many relationship between Event and Session is built via referential constraint.
/// Data sharing should be enabled
try provider.add(definingQuery: OfflineODataDefiningQuery(name: "Sessions_10000",
                                                     query: "/Sessions?$filter=EventID eq 10000L",
                                                     automaticallyRetrievesStreams: false))

/// Data sharing should be enabled
try provider.add(definingQuery: OfflineODataDefiningQuery(name: "Tracks_10000",
                                                     query: "/Tracks?$filter=EventID eq 10000L",
                                                     automaticallyRetrievesStreams: false))

/// User Specific data; data sharing should be off
try provider.add(definingQuery: OfflineODataDefiningQuery(name: "UserSessionAgendas",
                                                     query: "/UserSessionAgendas?$filter=EventID eq 10000L",
                                                     automaticallyRetrievesStreams: false))

/// Data sharing should be enabled
try provider.add(definingQuery: OfflineODataDefiningQuery(name: "Features",
                                                     query: "/Features",
                                                     automaticallyRetrievesStreams: false))

In the application configuration file, reference each defining query using the same name as the one written in the source code (the first parameter to the OfflineODataDefiningQuery constructor), as shown in the following example:

[defining_query]
name=Events_10000
is_shared_data=Y
download_interval=10
track_deltas=AUTO
delta_token_lifetime=36000

[defining_query]
name=UserSessionsAgendas
is_shared_data=N

In the example, the defining query Events_10000 is declared as shareable, which means that the event and related features can be accessed by all users.

Usually, you'll specify defining queries before opening the offline store for the first time, but they can also be added or removed afterwards if appropriate. You can use the getDefiningQueries method from the OfflineODataProvider class to fetch all existing defining queries.

Keep the following in mind when writing defining queries:

  • Currently, only defining queries where the resource path identifies an entity set or entity type instance (a single entity) are supported.
  • Shared defining query names must be unique, and must be identical on both the client and server. Otherwise, expected settings will not be applied to the correct defining query and the query will be using the default settings instead.
  • If you are using a mix of delta enabled and non-delta enabled defining queries, and you are using referential constraints to build relationships, the dependent entity in a relationship cannot be in a delta enabled defining query if the principal entity is in a non-delta enabled relationship. For example, say you have two defining queries, Events and Sessions (based on the sample metadata). Since there is a referential constraint between them and no expands are specified, the mobile service automatically uses the referential constraint to build relationships. The events are principal entities and the sessions are dependent entities. If the Events defining query is not delta enabled, then the Sessions defining query must not be delta enabled. However, if the Events defining query is delta enabled, the Sessions defining query may or may not be delta enabled.
  • If you are not using deltas, you can use the same entity sets in more than one defining query, but you cannot perform a selective download of one of those defining queries without the others.
  • If you are using a mix of delta enabled and non-delta enabled defining queries, you cannot use the same entity set in both a delta enabled and a non-delta enabled defining query, either directly referenced in the resource path or through an $expand.

Removing Defining Queries

You can always remove a stream-defining query. For non-stream defining queries, before opening the offline store, if a defining query is specified for the first time then you can remove it immediately. After opening the offline store, in the default configuration, neither existing defining queries, nor new specifying defining queries can be removed. To remove a defining query and its entities in the local store, you need to set allow_defining_query_removal to Y. This will allow the server and local store to keep track of the mapping between defining queries and entities. If you do not need to remove any general defining queries, leave allow_defining_query_removal to N for better performance. Turning allow_defining_query_removal on or off will cause the server to reinitialize the offline store for the client during a download. This will take more time than the normal download and if the client has any pending changes, they will not take place until pending changes are uploaded or deleted.

Using Defining Queries to Build Entity Relationships

To build relationships in your application, you can use $expand in queries, referential constraints, or a combination of the two.

$expand in queries : Use $expand in queries to build relationships between entity sets only if you are not tracking deltas, or if you are tracking deltas using the mobile service. You cannot use $expand in queries if you are tracking deltas using the OData service.

Referential constraints : If you are tracking deltas using the OData service and require entity relationships in the offline store, you cannot use $expand in queries but instead must have associations with referential constraints. Ensure that each defining query references a single entity set. The mobile service detects the associations with referential constraints and uses these referential constraints to build relationships between the entity sets selected in your defining queries.

1
For example, the sample metadata document has an association between Event and Session, called `Event_Session_One_Many0`, which defines a referential constraint. If you specify two defining queries, `/Events` and `/Sessions`, the server uses the referential constraint defined in the association `Event_Session_One_Many0` to build relationships between the `Events` and `Sessions` entity sets in the offline store.

Combining referential constraints and $expand in queries : When you use $expand to expand the relationship between two top-level entity sets, an association set is being implicitly referenced. For example, /Events?$expand=Sessions implicitly references the Event_Session_One_Many0Set association set. The mobile service allows you to mix referential constraints and $expand to build relationships.

 1
 2
 3
 4
 5
 6
 7
 8
 9
10
11
12
13
14
15
16
17
Consider the following example, which uses entity sets from the sample metadata:

```
~/Events?$expand=Sessions
~/Tracks
```

Relationships between events and sessions are computed using `$expand` and relationships between events and tracks are computed using referential constraints.

However, you cannot mix referential constraints and `$expand` for the same implicitly referenced association set. In the example below, relationships between events in Canada and their sessions are built using `$expand`, where the `Event_Session_One_Many0Set` association set is implicitly referenced. Although there is an association `Event_Session_One_Many0` with referential constraint between the Event and Session entity type, the referential constraint will not be used by the second and the third defining query to build other relationships since the referential constraint also implicitly references the same association set. As a result, relationships between events in the US and their sessions are not built. Hence, only for events in Canada one can use the Sessions navigation property to get associated sessions. For events in the US, one must use the `EventID` property in a filter to get the associated sessions.

```
~/Events?$expand=Sessions&$filter=Country eq 'CAN'
~/Events?$filter=Country eq 'US'
~/Sessions
~/Tracks
```

!!! note This is not an exhaustive list. The choice of defining query is highly dependent on the needs of the offline application.

The table below lists parameters that can be used to configure defining queries in an application configuration file.

Parameter Value Notes
name DefiningQueryName (Required) Name of the defining query.
is_shared_data N \| Y Whether the data is shared among different clients or users.
  • N Some data is not shared among multiple clients.
  • Y Data retrieved by the query is shared among multiple clients.
The default value is N.
refresh_interval NNN The interval time, in minutes, between downloads of the shared data. The default is 15 minutes.
track_deltas AUTO\|ALWAYS\|NEVER How to track OData deltas.
  • AUTO If the OData service supports delta change tracking on the defining query, the delta links returned are used when downloading the data.If the OData service does not support delta change tracking on the defining query, the mobile service tracks the changes so that only changed data is exchanged between the client and the mobile service.
  • NEVER Sets the mobile service to never track delta changes.If the OData service supports delta change tracking, the delta links returned by the OData service are used when downloading data, even if this option is specified.
  • ALWAYS Sets the mobile service to always track delta changes. This option is equivalent to AUTO if the OData service does not support delta change tracking on the defining query.
The default value is AUTO.
delta_token_lifetime NNN The time, in minutes, until the OData delta token expires. While a token is valid, only changed data is downloaded to the offline store. When the delta token expires, the entire data set is replaced. The default is 72000 minutes (50 days).

Last update: November 5, 2020