Osy#betaRun it on Osyrin: osyrin.com

Reference / Entity

[OnDelete]

[OnDelete(Remove)] Entity <Member>; · [OnDelete(Clear)] Entity? <Member>; · [OnDelete(Keep)] Entity <Member>;

`[OnDelete]` on an `Entity` member says what deleting the row it references does to the row holding it: Remove deletes it too, Clear empties the member, Keep (the default) leaves it, reading null.

stable1 example compiled by CIentitymodelrelationsdelete

Summary#

An Entity member can reference a row of any type, so no foreign key in the database can say what deleting that row does. [OnDelete] says it:

ruledeleting the referenced row…
Removedeletes this row too, in the same commit — a notification goes with the record it is about
Clearempties the member (and the type kept beside it); the member must be optional (Entity?)
Keep (default)leaves it: the member keeps the key and reads null, as a row the reader may not read does

Signature#

[OnDelete(Remove)] Entity <Member>;
[OnDelete(Clear)]  Entity? <Member>;
[OnDelete(Keep)]   Entity <Member>;   // the same as writing nothing

Description#

When does it run?#

In the delete itself: deleting a row deletes (Remove) or empties (Clear) every row whose member references it, in the same unit of work and the same commit, together with whatever those deletes cascade to. A rule costs one statement per entity type that declares it, whatever the number of rows; Keep costs nothing.

Why is Keep the default?#

Because it is the one that destroys nothing. A question answered about a piece of work, an audit line, a comment: what was said stays when the thing it was about is gone, and reads null where the thing was. Choose Remove for what is meaningless without its record, and Clear for an optional pointer to it.

Where is it allowed?#

Only on an Entity member. A reference to one type (Ticket Ticket;) is a database foreign key with its own rule (see relations). Clear on a [Required] or non-nullable member is refused — it would leave a required member empty.

Examples#

entity Task {
  [Required, MaxLength(200)] string Title;
  security { allow read, create, delete when IsAuthenticated; }
}

entity Reminder {
  [Required, MaxLength(200)] string Text;
  [Required, OnDelete(Remove)] Entity About;       // a reminder about a deleted task goes with it
  [OnDelete(Clear)] Entity? LastOpened;            // a pointer to it is emptied
  Entity? From;                                    // kept, and reads null
  security { allow read, create, delete when IsAuthenticated; }
}

public int RemindersLeftAfterDeleting(Task t) {
  t.Delete();
  UnitOfWork.Commit();
  return Reminder.Count();
}

See also#

Related

Entity

`Entity` is a reference to a row of ANY type the app keeps — what a notification, a comment or a question "about some…

relations

One entity points at another by declaring it as a member — that is the foreign key. The parent reads its children back…

Records — what any record is called, where it opens, who may read it

`Records.*` answers facts about a row of ANY type from what the app declared — what it is called (`[Title]`), where it…