As of now: up to 18.3 and earlier versions of Dynamics 365 Business Central, Partial Records feature has been fully implemented by default for
- API Pages
- Reports
As duly written officially in Partial Records - Business Central | Microsoft Docs
Considering Web Client (or clients in general), it has been declared by product group as not implementing partial records feature in all UI pages.
Therefore, up to now, every time it is required the implementation of Partial Records within the Web Client UX, it is required to analyze its performance before and after applying the code changes (typically using SetLoadFields statement).
A typical example to consider, could be the one reported in this GitHub entry that also shares objects and repro steps: Partial Records in Pages: setloadfields does not work fine · Issue #6672 · microsoft/AL · GitHub
Just to summarize:
- Extension 1: contains 4 Table Extension Fields to extend Fixed Assets table
field(50090; "JALSLFE1 UNE Class"; Code[20])
field(50091; "JALSLFE1 Used for"; Option)
field(50092; "JALSLFE1 Used Code"; Code[20])
field(50093; "JALSLFE1 UNE Description"; Text[50])
- Extension 2: contains a Page that uses only few fields
field("No."; Rec."No.")
field(Description; Rec.Description)
field("Description 2"; Rec."Description 2")
field("Vendor No."; Rec."Vendor No.")
and the same setloadfields(Description, "Description 2", "Vendor No."); within all typical page triggers
trigger OnFindRecord(Which: Text): Boolean
trigger OnOpenPage();
trigger OnAfterGetRecord();
trigger OnAfterGetCurrRecord();
trigger OnInit();
TROUBLESHOOTING and OUTCOME
When opening the page, the server first fills in all the rows to show (by default: the first 50 rows are loaded).
In this scenario, for that rows, the following fields are selected for loading and their corresponding values, notice how e.g. field three (Search Description) is not loaded (null value) and many others
The default platform database produces the following SQL query:
SELECT TOP (@0) "5600"."timestamp","5600"."No_","5600"."Description","5600"."Description 2","5600"."Vendor No_",DATALENGTH("5600"."Picture"),"5600_e1"."JALSLFE1 Used for","5600"."$systemId","5600"."$systemCreatedAt","5600"."$systemCreatedBy","5600"."$systemModifiedAt","5600"."$systemModifiedBy"
FROM "Navision_PlatformCore".dbo."CRONUS International Ltd_$Fixed Asset$437dbf0e-84ff-417a-965d-ed2bb9650972" "5600" WITH(READUNCOMMITTED)
JOIN "Navision_PlatformCore".dbo."CRONUS International Ltd_$Fixed Asset$d35ba5b7-eeb8-4bcc-8203-b2b053349f4b" "5600_e1"
WITH(READUNCOMMITTED) /* REPOS */ ON ("5600"."No_" = "5600_e1"."No_") WHERE ("5600"."No_">@1) ORDER BY "No_" ASC OPTION(FAST 50)
This happens for all the next rows loaded to be shown (14 in the default platform database).
After all of these 14 rows have been loaded but before they are sent to the client, the server repositions to the first row (still only loading the 14 fields).
The server is now done loading data and resets Partial Records on the page's record: this is the current default behavior.
The client then calls the server to call the OnAfterGetCurrRecord trigger.
Since Partial Records is no longer enabled on the page's record, all fields are loaded when the server positions the form's record on the first row. This re-positioning is actually implemented as a GET call.
Notice the SetLoadFields call is coming in the trigger OnAfterGetCurrRecord, which as the name suggests, happens after the row has been loaded.
trigger OnAfterGetCurrRecord();
begin
setloadfields(Description, "Description 2", "Vendor No.");
toStopDebug += 1;
end;
In this case, it is just required to remove the full load since it happens when the client refreshes the first row, the client only does this if the page implements the OnAfterGetCurrRecord trigger.
Try to remove the trigger on the page and then the extra full load is removed.
The customer / partner might be seeing the subsequent call to that happens to the server to reposition onto the first row (the OnAfterGetCurrRecord).
That happens with all fields selected until Partial Records will automatically be UI pages.
This is one of the reasons why product group currently are NOT automatically enabling Partial Records on all UI pages.
RESULTS AND TAKEAWAYS
There could be a few reasons why experiencing a JIT load within UI pages and strange behaviors:
- Within debugging or tracing, it might be seeing the subsequent call to that happens to the server to reposition onto the first row (the OnAfterGetCurrRecord).
This is the current case. That happens with all fields selected until Partial Records will automatically be UI pages. - Event subscribers accessing other fields:
If there are other extensions that might access these extra fields, then they will be loaded via a JIT load and afterwards selected for subsequent loads.
In general, product group do not support Partial Records on UI pages, yet, as reported in the official documentation.
There might be chances that at some point product group could support Partial Records automatically on UI pages, so there would not be any need to write additional code (SetLoadFields) as it might be implemented via runtime by default. There is no ETA nor guarantee on this, as of now.