MB-500 cheat sheet
MB-500 · Keep the key ideas within reach.
Plan the architecture and solution design
A model is the unit of compilation and can declare dependencies on other models; a package is the deployment unit and can contain one or more models.
Model layering order from highest to lowest is USR, CUS, VAR, SYS; a USR-layer extension overrides the same element extended in a lower layer.
Extension element types include table, form, view, map, enum, EDT, class, data entity, menu item, and security role/privilege/duty extensions.
Chain of command can wrap instance methods of classes, tables, forms, and form data sources; it cannot be applied to static methods or methods marked final.
Pre/post method event handlers ([PreHandlerFor], [PostHandlerFor]) are the fallback when CoC is not possible, such as static methods and delegates.
Two models cannot overlay the same element in the same layer; supported designs use extensions so the solution remains upgradeable.
Decision rule: adding a field to an existing table = table extension; a new business process = a new model with a reference to the model that owns the base elements.
Deployment path: build a deployable package on a build VM, upload it to the LCS asset library, apply to sandbox, then promote to production.
Apply developer tools
Model management is accessed in Visual Studio at Dynamics 365 > Model management > Create model / Install model into the development workspace.
Build > Build Solution compiles X++ and runs Best Practice checks; BP errors fail the build while BP warnings do not.
Deployable packages are generated on a build VM or through an Azure DevOps build pipeline, not on the one-box development VM.
Source control is Azure DevOps TFVC or Git; in Git repositories X++ elements are stored as individual .xpp files.
Task recorder captures user actions and produces a recording that can become BPM process documentation or an RSAT automation script.
Trace Parser consumes a client trace file and reports slow SQL statements and X++ call-tree time so bottlenecks can be located.
The Table browser add-in (Dynamics 365 > Addins > Table browser) previews table contents directly from the development workspace.
Visual Studio Test Explorer discovers SysTest classes in the project and runs all tests or a selected subset against the dev environment.
Design and develop AOT elements
Table types are Main, Transaction, Worksheet, Parameter, Group, and Reference; the table type drives the form pattern and runtime behavior.
Every table requires a unique primary index; the cluster index is normally the primary index built on RecId.
A unique index designated as the alternate key is required for tables exposed as public OData data entities.
Data entities need Public = Yes, a public collection name, and Data management enabled; building the entity generates its staging table.
Computed columns in views are defined with SysComputedColumn static methods that return a SQL expression string.
Menu item types are Display (form), Action (class or report), and Output (SSRS report); an item takes effect only when added to a menu or menu extension.
Delete actions: Cascade deletes child rows, Restricted blocks deletion when children exist, Cascade+Restricted checks for children first and then cascades.
Labels must be defined in a label file and referenced as @FileID:LabelID; hard-coded strings trigger Best Practice errors.
An enum with IsExtensible = Yes accepts new elements from other models; a non-extensible enum cannot be extended.
Develop and test code
ttsbegin and ttscommit delimit a transaction; ttsLevel() returns nesting depth, and a rollback at the outermost scope discards all nested work.
Set-based statements insert_recordset, update_recordset, and delete_from execute a single SQL statement and should replace row-by-row loops.
RecordInsertList and RecordSortedList buffer rows in memory and persist them with one insertDatabase() call.
Useful select modifiers: firstonly, forupdate (requires a transaction), exists join, notexists join, crossCompany, and an explicit field list.
SysOperation pattern: a service class holds the logic, a data contract carries parameters ([DataContract]/[DataMember]), and a SysOperationServiceController runs it, optionally with a UIBuilder.
Throw with error() or checkFailed(); catch with catch(Exception::Error) or catch(Exception::UpdateConflict) and use retry after a conflict.
changeCompany() switches the legal entity context for the enclosed block and restores the previous company when the block exits.
Unit tests extend SysTestCase, mark methods with [SysTestMethod], and run from Visual Studio Test Explorer or the build pipeline.
Implement reporting
An SSRS report combines a query or RDP class, a temporary table, and a report design (.rdl), all shipped in a deployable package.
The RDP class extends SRSReportDataProviderBase, is decorated with [SRSReportQueryAttribute] and [SRSReportParameterAttribute], and fills a temp table marked [SRSReportDataSetAttribute].
Electronic Reporting uses three configuration types - data model, model mapping, and format - so a format can be changed without a code deployment.
ER destinations determine output routing: screen, file, email, archive, or Power BI.
The entity store holds aggregate measurements and dimensions refreshed from the transactional database for embedded Power BI and analytics.
Bring your own database (BYOD) exports data entities to an Azure SQL database on a schedule for external reporting tools.
Financial reports (Management Reporter) are built from row definitions, column definitions, and reporting trees rather than X++ code.
The Document Routing Agent is a client-side service that enables network printing of SSRS reports from the browser client.
Integrate and manage data solutions
A DMF project selects data entities, source format, field mapping, and processing order; records validate in the staging table before transfer to target tables.
Recurring integrations poll a folder or Azure Blob container on a schedule and write processing results and error files back to the source location.
OData exposes public data entities at /data/{EntityName}; callers authenticate with an Azure AD app registration and an OAuth bearer token.
A custom service is an X++ class whose methods are marked [SysEntryPointAttribute], placed in a service group, and consumed over SOAP or JSON.
Business events publish a contract payload to a configured endpoint when a business action occurs, without polling the database.
Dual-write performs near real-time synchronization between finance and operations apps and Dataverse; it requires a matching legal entity and a configured dual-write link.
Import modes are create, update, and upsert; set-based execution processes the staging set in one operation while per-record execution processes row by row.
Enabling change tracking on a data entity lets downstream systems export only inserted, updated, and deleted records since the last run.
Implement security and optimize performance
Security hierarchy: roles contain duties, duties contain privileges, and privileges grant permissions to entry points, tables, fields, and data entities.
Extensible data security is a policy composed of a query, one or more constrained tables, and a context type such as role, user, company, or custom.
CodeAccessPermission::assert() and demand() enforce permissions in code, and RunAs executes code under a temporary elevated user context.
Avoid select statements inside loops; replace them with joins, exists join, or set-based data operations.
Indexes should cover the fields used in where and order by clauses, and included columns avoid key lookups on wide tables.
Caching options are SysGlobalCache, Global::cache, and record caching; volatile data should not be cached.
Long-running work belongs in the batch framework, typically driven by a batch-enabled SysOperationServiceController.
Performance diagnostics use SQL trace plus Trace Parser, LCS SQL insights, and environment monitoring.