Creating and Deleting Entities¶
You can execute POST
requests to create entities locally.
Understanding Keys¶
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 readLink
¶
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 loadEntity()
method.
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.
Deleting Entities¶
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 editLink
¶
You can use either readLink
or editLink
to identify an entity for modification. In most cases, readLink
and editLink
have the same URL, but it's recommended that you adhere to their intended usage when leveraging them to read, update or delete.