How Are Tables, Columns and Views Stored?
A look into the Entities block of the customizations.xml. What tables, attributes and views really look like in the export.
The largest block in almost every customizations.xml of a D365 solution export is "Entities". Whoever understands how it is built can answer the core questions about a data model directly from the export. Building queries in tools like the XrmToolBox then becomes easy. This article looks at the structure in detail.
The table itself
Every table begins with an "Entity" element. Inside is an "EntityInfo" block with the basic data: the technical name of a table, the display name in all installed languages (as "LocalizedNames" with language codes), the description and the ownership model. On top come dozens of behavior switches, from enabling audit to the question of whether the table shows up in the quick find index.
Precision pays off even here. The description of a table is stored as a "Descriptions" element right next to the names. If it is empty, it was never maintained, and you can count that for all tables of a solution in a minute. Not every consultant documents the business logic. Still, thinking one step further, it matters for AI workflows to understand the system.
The columns
Under "attributes" there is one "attribute" element per column. The most important details:
- Name and PhysicalName: the technical name including the prefix, from which you can read which publisher created the column.
- Type: the data type, from "nvarchar" through "picklist" to "lookup". For choice columns, the options with value and label hang directly below, unless it is a global choice.
- RequiredLevel: the requirement level. A stock full of required columns tells you something about the data quality you can expect.
- Description and display names: again localized, again countable.
A single column looks like this in the export, schematically:
<attribute PhysicalName="fab_budget">
<Type>money</Type>
<Name>fab_budget</Name>
<LogicalName>fab_budget</LogicalName>
<RequiredLevel>none</RequiredLevel>
<displaynames>
<displayname description="Budget" languagecode="1031" />
</displaynames>
<Descriptions>
<Description description="Freigegebenes Projektbudget (netto)" languagecode="1031" />
</Descriptions>
</attribute>
What is not stated here: whether the column is filled. The export knows the structure, not the data.
The views
Views are called "savedqueries" in the export and also sit under the table. Each consists at its core of two embedded definitions. The "fetchxml" is the query with columns, filters, joins and sorting. The "layoutxml" defines which columns are shown and at what width.
Both are XML inside XML, so they have to be read separately. In return they are surprisingly talkative. From the fetchxml you can read which columns a view really uses, and whether two views are identical except for the name. Such duplicates arise when copying and then sit around for years.
Forms and relationships as neighbors
The same table block also holds the forms ("FormXml", again embedded XML, split by form type). Outside the Entities block sit the relationships with their cascading behavior. Both deserve a closer look of their own but follow the same pattern: the export describes the complete structure, spread across nested definitions.
Whoever has gone through this once by hand also understands why tools exist for it. Not because the information is hidden, but because it is spread across thousands of elements that are trivial one by one and unmanageable in sum.
This article was originally written in German and translated into English with the help of AI. Read the German original.
Upload your solution export and get an assessment within minutes: security risks, technical debt, documentation coverage, and migration risk. No access to your environment required, first metrics free of charge.
Analyze your solution View sample report