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
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.
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
RecIdorTableIddirectly on a field — use EDTs derived fromRefRecId/RefTableIdinstead. - Set the display length and style properties to
Autounless 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 rawRecId/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.