Creating and Deleting Entities¶
You can execute
POST requests to create entities locally.
Keys or Key Values : In many cases, the back-end OData service generates key values for key properties when a new entity is created (key of an entity may consist of multiple properties). This implies that an entity created locally (offline) may not have key values until an upload and a subsequent download is performed. Although key values may be assigned when the entity is created locally, the values may be omitted or overwritten by the back-end OData service. Therefore, key values assigned locally cannot be treated as permanent.
1 2 3
Uniqueness of Keys : When you create a new entity locally, the key values can be partially or wholly available locally if the application specifies any of them. The back-end OData service MAY change them even if the application specifies them. An entity created locally that has not been uploaded and downloaded can always be identified by its entity ID which contains a generated value. The offline store only enforces uniqueness for keys of new entities if all the key properties are specified and are all non-null. If even a single key property is null/unspecified, offline store does not check for uniqueness. As a result, the developer has two choices regarding assignment of key properties for a new entity:
1 2 3 4
Create Entity without Setting Key Property Values¶
The sample below calls the constructor without setting default property values. That means, the new event does not have an ID when being created locally. You can create as many as you want events locally in the same way without getting the duplicate key exception. The back end will generate IDs for all events.
/// Declare a new Event entity without setting properties to default values by passing false to the constructor. /// The entity key, eventID, will be unset let event = Event(withDefaults: false) /// Set property values event.country = "USA" event.name = "SAP Summit" /// Create a local Event entity try eventService.createEntity(event)
In the sample below, if you call a generated proxy class constructor without any parameters, the event you create will have its properties set to their respective default values. For example, if the key is an integer, the key property will have 0 as its value. Line 9 unsets ID of the event, giving the back end an opportunity to generate the real ID.
/// Assign default property values at proxy class instance construction let event = Event() /// Set property values event.country = "USA" event.name = "SAP Summit" /// Unset entity key explicitly event.unsetDataValue(for: Event.eventID) /// Create a local Event entity try eventService.createEntity(event)
If line 9 (calling the
unsetDataValue() method) was not present, the new event would have 0 as its ID. Attempting to create a second event constructed in the same way without setting the key property will cause a duplicate key exception as both the two events would have a key property of integer type 0 as ID. Two events with the same ID is not allowed.
To access a newly created entity without key values, retrieve the
readLink (read URL) from the entity after the
createEntity() method has been performed. The
readLink construction uses the locally generated entity ID that uniquely identifies the entity.
/// Not to set default value at proxy construction let track = Track(withDefaults: false) /// Set property values track.name = "Keynote" /// Create a local Track entity try eventService.createEntity(track) /// readLink is available after createEntity() call let readLink = track.readLink ... /// Use loadEntity() to read back the entity via readLink later. /// It is important to declare a new entity without the entity key /// being set to default value let readBackTrack = Track(withDefaults: false) readBackTrack.readLink = readLink try eventService.loadEntity(readBackTrack)
Further Notes for
If you need to apply other query options, for example, select on certain properties or expand on others, create a new
DataQuery with appropriate characteristics and use as the second parameter of the
Alternatively, you can use the
withURL() method, but additional query options require you to directly specify the OData request.
let query = DataQuery().withURL(readLink) let track = try eventService.fetchTrack(matching: query)
An entity that is downloaded has its
readLink constructed using the actual key from the OData service. In addition, the value derived from the actual key replaces the entity ID generated locally. However, the
readLink that is retrieved immediately after
createEntity(), with a generated entity ID is still usable. Maintaining the entity's ID mapping information helps to simply
readLink usage and to avoid a dangling reference. The advantage of
readLink is its usage regardless whether the entity has been created, uploaded, or downloaded.
You can delete an entity, no matter it is downloaded from the OData service or created locally and not uploaded yet.
You can directly delete an entity, or use
editLink of an entity for deletion.
/// Get editLink of an entity let editLink = track.editLink ... /// Delete an entity with the editLink let trackToDelete = Track(withDefaults: false) trackToDelete.editLink = editLink try eventService.deleteEntity(trackToDelete)
A download may take place before any upload. An entity deleted locally remains in deleted mode even if the download informs that the entity has been deleted from the OData service. This means a queued delete request will cause a failure when it is uploaded. A second upload and download will resolve this issue.
Further Notes for
You can use either
editLink to identify an entity for modification. In most cases,
editLink have the same URL, but it's recommended that you adhere to their intended usage when leveraging them to read, update or delete.