Skip to content

Overview

You can perform OData operations (by executing OData requests) to modify data in an offline store, including creating, deleting and modifying entities as well as relationships.

Modifying offline data is similar to the online case. The difference with offline case is that requests are added to a queue and will be sent (when performing an upload) to the back end later. The changes are local without affecting the back end until you perform an upload.

All requests are stored into RequestQueue Entity

RequestQueue Entity Properties

Each entity in the RequestQueue entity set has the following properties:

Name Type Description
RequestID Edm.Int64 An incrementing unique integer assigned to each request.
Status Edm.String The value to indicate the status of this request: whether sent to the server, successfully or failed
Method Edm.String The HTTP method of the request (POST, PUT, PATCH, DELETE, and so on).
URL Edm.String The URL of the request.
Body Edm.String The payload of the request.
CustomTag Edm.String The value of the custom tag field of the request (if a value for the custom tag field was specified when sending the request).
AffectedEntity Navigation Property A navigation property that navigates from the request to the entity in the offline store that is affected by the request.
DependentRequests Navigation Property A navigation property that navigates from the request to those requests in the offline store that depend on the request.
CustomHeaders Navigation Property A navigation property that navigates from the reques to those custom headers in the offline store.

CustomHeaders is a navigation property based on the CustomHeader entity type. However, accessing the CustomHeaders entity set directly via the dynamic API is not permitted. Instead, you can retrieve the custom headers attached to this request by using the $expand query on this navigation property.

CustomHeader entity has the following properties:

Name Type Description
HeaderID Edm.Int An incrementing unique integer assigned to each header.
Name Edm.String The head name.
Value Edm.String The header value.

The RequestQueue is an exceptional type of entity set, meaning it only allows access to view and erase entries, but it doesn’t support adding new entries or changing existing ones.

The following code example shows how to access RequestQueue using the dynamic API:

// Set up the entity set, entity type, and properties for RequestQueue
EntitySet requestQueueSet = dataService.getEntitySet("RequestQueue");
EntityType requestQueueType = requestQueueSet.getEntityType();

// Navigation property
NavigationProperty affectedEntityProp = (NavigationProperty)requestQueueType.getProperty("AffectedEntity");
NavigationProperty dependentRequestsProp = (NavigationProperty)requestQueueType.getProperty("DependentRequests");
NavigationProperty customHeadersProp = (NavigationProperty)requestQueueType.getProperty("CustomHeaders");

// Structural properties
Property requestIDProp = requestQueueType.getProperty("RequestID");
Property statusProp = requestQueueType.getProperty("Status");
Property methodProp = requestQueueType.getProperty("Method");
Property urlProp = requestQueueType.getProperty("URL");
Property bodyProp = requestQueueType.getProperty("Body");
Property customTagProp = requestQueueType.getProperty("CustomTag");

//Also can add filter here
DataQuery requestQueueQuery = new DataQuery().from(requestQueueSet);

// See if there are any requests in the RequestQueue
long nRequests = dataService.executeQuery(requestQueueQuery).getCount();

// Get the list of requests in the RequestQueue
EntityValueList requests = dataService.executeQuery(requestQueueQuery).getEntityList();

// Examine the first request entry
EntityValue request = requests.get(0);

// Check for status returned
String status = statusProp.getString(request));

// Request method: POST, PUT, DELETE, et cetera
String method = methodProp.getString(request);

// Request URL (OData request)
String requestURL = urlProp.getString(request);
/// Set up entity set, entity type and properties for RequestQueue
let requestQueueSet: EntitySet = dataService.entitySet(withName: "RequestQueue")
let requestQueueType: EntityType = requestQueueSet.entityType

/// Navigation property
let affectedEntityProp = requestQueueType.property(withName: "AffectedEntity")
let dependentRequestsProp = requestQueueType.property(withName: "DependentRequests")
let customHeadersProp = requestQueueType.property(withName: "CustomHeaders")

/// Structural properties
let requestIDProp = requestQueueType.property(withName: "RequestID")
let statusProp = requestQueueType.property(withName: "Status")
let methodProp = requestQueueType.property(withName: "Method")
let urlProp = requestQueueType.property(withName: "URL")
let bodyProp = requestQueueType.property(withName: "Body")
let customTagProp = requestQueueType.property(withName: "CustomTag")

/// Also can add filter here
let requestQueueQuery = DataQuery().from(requestQueueSet)

/// See if there are any requests in the RequestQueue entity set
let nRequests = try dataService.executeQuery(requestQueueQuery).count()

/// Get the list of requests in the RequestQueue entity set
let requests = try eventService.executeQuery(requestQueueQuery).entityList()

/// Examine the first request entry (giving that there is at least one request)
let request = requests.first()

/// Get request ID
let requestID = requestIDProp.longValue(from: request)

/// Get request body
let requestBody = bodyProp.stringValue(from: request)

/// Get Http Status Code returned
let status = statusProp.stringValue(from: request)

/// Get request method: POST, PUT, DELETE, et cetera
let method = methodProp.stringValue(from: request)

/// Get request URL (OData request)
let url = urlProp.stringValue(from: request)

/// Use the values
...

When an entity is removed from the RequestQueue, a cascade deletion process begins which deletes all requests that rely on the deleted entity. The process unfolds in the following manner:

The procedure begins by identifying the entity object to be erased. This object comprises a DependentRequests section, which lists all other requests that are directly tied to it. Every request listed in this section is deleted in the next phase.

During this deletion of dependent requests, each request’s own DependentRequests field is scrutinized. For each one of these requests, the deletion step is repeated in a recursive cycle until no more dependent requests can be found.

This thorough process ensures every request - even those indirectly related, that are reliant on the original deleted entity is also completely removed. Therefore, when one request is taken out, every other request linked to it is also eliminated in a synchronized process, thereby maintaining the coherence and completeness of the data.

Note

The code samples in this topic use the sample OData service metadata.


Last update: January 4, 2024