✏️ Explanatory Question

What are table relations in Dynamics 365 Finance & Operations, and what is the purpose of a DeleteAction? Explain the four delete action types — None, Cascade, Restricted, Cascade+Restricted — and where the relation should be defined.

👁 1 Views
📘 Detailed Answer
🟢 Easy
💡

Answer with Explanation

D365 F&O • X++ INTERVIEW

Table Relations & DeleteActions in Dynamics 365 Finance & Operations

Question 15 — Defining relationships and controlling what happens to child records on delete.

Interview Question

What are table relations in Dynamics 365 Finance & Operations, and what is the purpose of a DeleteAction? Explain the four delete action types — None, Cascade, Restricted, Cascade+Restricted — and where the relation should be defined.

Model Answer (Short)

A table relation defines how two tables are linked, usually through a foreign-key to primary-key association, and it drives lookups, joins and referential integrity. A DeleteAction is a rule placed on the parent table that specifies what happens to related child records when a parent record is deleted. The four types are None (do nothing to children), Cascade (delete the children too), Restricted (block the delete if children exist), and Cascade+Restricted (restrict on a direct user delete but cascade when triggered programmatically). Relations are normally defined on the child table, while the DeleteAction is defined on the parent.

The Four DeleteAction Types

Delete actions explained

  • None — the parent record is deleted, but the child records are left untouched. Use with care as it can create orphan records.
  • Cascade — when the parent is deleted, all related child records are also deleted automatically. Use when children cannot logically exist without the parent.
  • Restricted — the parent can be deleted only if no child records exist. If children are present, the delete is blocked and the user is warned.
  • Cascade+Restricted — if a user deletes the parent directly and children exist, it behaves like Restricted (blocked); but if the delete is triggered programmatically from a higher-level cascade, it behaves like Cascade.
WHERE TO DEFINE
Relation = on child table  •  DeleteAction = on parent table

Best practices for relations

  • The relation name should contain the name of the related table for clarity.
  • Define the relation on the table holding the foreign key — usually the child table.
  • Prefer relations based on primary key ↔ foreign key wherever applicable.
  • DeleteActions help maintain database consistency when related records exist across tables.

Prerequisites (Rule 5)

  • Visual Studio with the Dynamics 365 developer tools.
  • A custom model / package for your objects.
  • A parent and child table with a defined relation between them.
  • Understanding that DeleteActions fire through the delete() method (validated at both DB and kernel level).

Code Example — Cascade delete honoured automatically

With a Cascade DeleteAction from parent to child, deleting the parent removes children too:

AbcOrderHeader header;

ttsbegin;
select header
    where header.OrderId == 'ORD-0001';

if (header)
{
    // Because a Cascade DeleteAction exists on AbcOrderHeader -> AbcOrderLine,
    // all matching AbcOrderLine rows are deleted as part of this call.
    header.delete();
}
ttscommit;

Restricted delete — blocked when children exist

AbcOrderHeader header;

// With a Restricted DeleteAction, this throws / warns if lines exist
select header
    where header.OrderId == 'ORD-0001';

if (AbcOrderLine::existForHeader(header.OrderId))
{
    // Kernel will prevent the delete; handle gracefully in UI
    warning("Cannot delete order: order lines still exist.");
}
else
{
    header.delete();
}

Overriding delete() to add custom logic

public void delete()
{
    ttsbegin;

    // Custom pre-delete logic (e.g. archive the record)
    AbcOrderArchive::archive(this);

    super();   // runs the standard delete and honours DeleteActions

    ttscommit;
}

DeleteAction Behaviour Summary

DeleteAction User deletes parent (children exist) Cascade triggered from above
None Parent deleted; children left as orphans Children left untouched
Cascade Parent and children deleted Children deleted
Restricted Delete blocked / warning shown Children deleted (restriction skipped)
Cascade+Restricted Delete blocked (acts as Restricted) Children deleted (acts as Cascade)

Points the interviewer wants to hear

  • Relations link tables via PK ↔ FK; DeleteActions protect referential integrity.
  • Define the relation on the child, the DeleteAction on the parent.
  • Cascade deletes children; Restricted blocks the delete.
  • Cascade+Restricted = Restricted for direct user deletes, Cascade when triggered programmatically.
  • DeleteActions execute through the delete() method — overriding it still honours them via super().

Likely Follow-up Questions

  • What is the risk of using the None delete action?
  • How does Cascade+Restricted decide which behaviour to apply?
  • Do DeleteActions fire during a set-based delete_from? (Only if not skipped.)
  • Where is a relation best defined — parent or child table, and why?

Key Takeaway

Table relations connect data via PK ↔ FK, and DeleteActions keep that data consistent by deciding the fate of child records. Remember the split — relation on the child, DeleteAction on the parent — and pick Cascade, Restricted or Cascade+Restricted based on how children should behave when the parent is removed.