✏️ Explanatory Question

What is an Extended Data Type (EDT) and a Base Enum in Dynamics 365 Finance & Operations? How do they differ, when would you create each, and what are the key best practices when using them in tables?

👁 6 Views
📘 Detailed Answer
🟢 Easy
No previous question
No next question
💡

Answer with Explanation

D365 F&O • X++ INTERVIEW

Extended Data Types (EDT) & Base Enums in Dynamics 365 Finance & Operations

Question 7 — What they are, how they differ, and the best practices interviewers expect you to know.

Interview Question

What is an Extended Data Type (EDT) and a Base Enum in Dynamics 365 Finance & Operations? How do they differ, when would you create each, and what are the key best practices when using them in tables?

Model Answer (Short)

An EDT is a reusable, named data type derived from a primitive type (string, integer, real, date, container, guid, etc.) or from a reference type. It centralises properties such as label, help text, length and relations so that every field based on it inherits the same definition. A Base Enum is a fixed, named list of constant values (like a C# enum) — for example a status field with values such as Open, Released, Invoiced. Use an EDT when you want a consistent, reusable data type across many fields, and a Base Enum when a field can only hold one of a limited, known set of values.

Detailed Explanation

Extended Data Type (EDT)

  • Defines a reusable type with a consistent label, help text, length and style.
  • Can carry table relations, so any field using the EDT inherits lookups and links automatically.
  • Two kinds: primitive-based (string, int, real, date) and reference-based (e.g. RefRecId, RefTableId).
  • Best practice: create a new EDT only when no suitable one exists; if only the label differs, reuse the existing EDT and set the label at field level.

Base Enum

  • A fixed set of named constants, each with an underlying integer value and a label.
  • Ideal for fields with multiple fixed patterns such as type, status or division.
  • Reuse an existing enum whenever one matches; only create a new one when nothing fits.
WHEN TO USE WHICH
Reusable data type = EDT  •  Fixed set of values = Base Enum

EDT Best Practices

  • Create a subtype only when no appropriate standard EDT is available.
  • Fields holding the same information must share the same EDT for consistency.
  • Never use the system types RecId or TableId directly on a field — use EDTs derived from RefRecId / RefTableId instead.
  • Set the display length and style properties to Auto unless a specific value is required.
  • Don't pick an overly generic type just because it exists — define a purpose-specific EDT and reuse it.

Base Enum Best Practices

  • Always set the Label property on the enum and on every element.
  • For a mandatory table field, make the first element (value 0) a neutral "No Selection / N/A" with a blank label.
  • If you need an initial value, use zero.
  • Always compare against an enumerator, e.g. salesTable.SalesType == SalesType::Sales.
  • Never compare an enum against a numeric constant (e.g. == 1).
  • Never use relational operators (< > =) on enums, and never compare/assign between different enum types.
  • Before deleting or changing an enum value, consider the existing data already stored against it.

Prerequisites (Rule 5)

  • Visual Studio with the Dynamics 365 developer tools.
  • A custom model / package for your objects.
  • Label files for the labels used on the EDT / enum elements.

Code Example — Comparing a Base Enum correctly

SalesTable salesTable = SalesTable::find('SO-0001');

// CORRECT: compare against the enumerator
if (salesTable.SalesType == SalesType::Sales)
{
    info("This is a standard sales order.");
}

// WRONG: never compare against a raw number
// if (salesTable.SalesType == 3) { ... }

// WRONG: never use relational operators on enums
// if (salesTable.SalesType > SalesType::Journal) { ... }

Switching on an enum

switch (salesTable.SalesType)
{
    case SalesType::Journal:
        // handle quotation / journal
        break;

    case SalesType::Sales:
        // handle standard order
        break;

    default:
        // handle everything else
        break;
}

Using a reference EDT instead of RecId

// On a table, a field that references another record should use an EDT
// derived from RefRecId (e.g. an EDT named AbcOrderRefRecId),
// NOT the raw system type RecId.

AbcOrderLine orderLine;
orderLine.OrderHeaderRefRecId = orderHeader.RecId;   // typed via a RefRecId-based EDT
orderLine.insert();

EDT vs. Base Enum

Aspect Extended Data Type (EDT) Base Enum
Purpose Reusable data type with shared properties Fixed list of named constant values
Underlying value Primitive (string/int/real/date) or reference Integer mapped to each element
Carries relations Yes (can define table relations) No
Typical use Amounts, IDs, descriptions, references Status, type, category fields
Compared in code with Normal value comparison Enumerator (Enum::Value)

Points the interviewer wants to hear

  • EDT = reusable type with shared label/length/relations; Base Enum = fixed value list.
  • Reuse existing EDTs/enums before creating new ones.
  • Use RefRecId / RefTableId-based EDTs, never raw RecId / TableId.
  • Mandatory enum fields should have a zero = "No Selection" element.
  • Always compare enums against enumerators, never numbers or with relational operators.

Likely Follow-up Questions

  • Why should you avoid comparing an enum to a numeric constant?
  • What is the difference between a primitive EDT and a reference EDT?
  • Why is 0 = "No Selection" recommended for mandatory enum fields?
  • What must you check before removing a value from an existing Base Enum?

Key Takeaway

Use EDTs to enforce a consistent, reusable data definition across fields, and Base Enums for fields limited to a fixed set of values. Reuse before you create, prefer reference EDTs over raw RecId, and always work with enumerators in code.

No previous question
No next question