# [OnDelete]

> `[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.

<!-- id: entity-on-delete · area: entity · stability: stable · html: https://osysharp.com/reference/entity/on-delete/ -->

## Summary        {#summary}
An [`Entity`](https://osysharp.com/reference/types/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:

| rule | deleting the referenced row… |
|---|---|
| `Remove` | deletes this row too, in the same commit — a notification goes with the record it is about |
| `Clear` | empties 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      {#signature}
```osy syntax
[OnDelete(Remove)] Entity <Member>;
[OnDelete(Clear)]  Entity? <Member>;
[OnDelete(Keep)]   Entity <Member>;   // the same as writing nothing
```

## Description    {#description}

### When does it run?   {#when}
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?   {#keep}
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?   {#where}
Only on an `Entity` member. A reference to one type (`Ticket Ticket;`) is a database foreign key with its own rule
(see [relations](https://osysharp.com/reference/entity/relations/)). `Clear` on a `[Required]` or non-nullable member is refused — it would leave a required
member empty.

## Examples       {#examples}

```osy title="removed with it, emptied, and kept" test app=entity-on-delete
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       {#see-also}
- [Entity](https://osysharp.com/reference/types/entity/) — the reference `[OnDelete]` governs
- [relations](https://osysharp.com/reference/entity/relations/) — a reference to one type, and its foreign key
- [Records — what any record is called, where it opens, who may read it](https://osysharp.com/reference/stdlib/records/) — what a reference that reads null was about, when it could still be read
