bcquality/microsoft/knowledge/performance/do-not-re-get-rec-inside-onaftergetrecord.md
Jesper Schulz-Wedde e570d6113f Extract 55 knowledge articles from BC review-agent prompt
Adds 55 articles (plus 76 code samples) spanning four new domains and
two existing domains, extracted from the internal Business Central
review-agent prompt. Content was filtered against BCQuality's
remedial-knowledge premise: each article encodes BC-specific behaviour,
a CodeCop rule, a platform API semantic, or an anti-false-positive
guideline that a capable LLM would otherwise get wrong.

New domains:
- privacy (11 articles): DataClassification inheritance semantics, the
  StrSubstNo-defeats-Error-telemetry-classification pitfall, Privacy
  Notice consent for outgoing requests, anti-false-positives for pages
  and in-memory data.
- upgrade (11 articles): upgrade-codeunit structure, upgrade-tag
  lifecycle and registration, protected DB reads, DataTransfer for
  large datasets, InitValue semantics, enum-ordinal preservation,
  obsolete-workflow, first-install detection.
- ui (9 articles): caption capitalization by phrase type, tooltip voice,
  teaching-tip vs tooltip, tour-tip conventions, character limits,
  banned terms, ampersand handling, title punctuation.
- style (11 articles): label-suffix convention, API page naming,
  temporary-variable prefix, label properties (Comment/Locked), named
  invocations, FieldCaption in user messages, OptionCaption pairing,
  Error-parameter passing, `this` keyword, required parentheses, file
  naming.

Gaps in existing domains:
- performance (11 articles): production-scale table catalog (no row
  counts, per internal-data concern), anti-false-positive for bounded
  tables, guard-before-Get ordering, redundant-Get-in-OnAfterGetRecord,
  LockTable in read-only helpers, combined ModifyAll passes, writes in
  OnAfterGetRecord, SetLoadFields heuristics, temporary-table
  regressions, FlowField source-table widening, MaintainSQLIndex
  disabling SIFT.
- security (2 articles): environment-specific hardcoded GUIDs,
  ValidateTableRelation=false on user input.

Intentionally excluded: specific production P95 row-count numbers
(aggregated internal telemetry); rewritten as categorical guidance on
which tables to treat as production-scale without publishing sizes.

All articles use `bc-version: [all]` (applies to every BC version, per
the new schema sentinel). Validator passes with 0 errors / 0 warnings.
2026-04-23 16:43:42 +02:00

1.6 KiB

bc-version domain keywords technologies countries application-area
all
performance
onaftergetrecord
get
rec
page-runtime
redundant-fetch
al
w1
all

Do not re-Get the current record inside OnAfterGetRecord

Description

The page runtime loads the current record before firing OnAfterGetRecordRec already holds the row's values when the trigger body runs. Calling Rec.Get(...) (or any equivalent Get against the same key) inside the trigger issues a second database round-trip for data the runtime just fetched. On a list page that displays hundreds of rows during a scroll, this turns into hundreds of wasted round-trips per user interaction. The same concern applies to OnAfterGetCurrRecord on card and document pages, though the impact is smaller because the trigger fires per selection rather than per row.

Best Practice

Read from Rec directly. When a helper method needs a different record, pass Rec as an argument or let the helper fetch its own lookup once; do not re-Get the current row. If the code truly needs a fresh value because it was modified by another session, design the refresh explicitly — document it in a comment — rather than paying the cost on every trigger fire.

See sample: do-not-re-get-rec-inside-onaftergetrecord.good.al.

Anti Pattern

An OnAfterGetRecord trigger body that starts with AssemblyLineRec.Get("Document Type", "Document No.", "Line No.") for the same keys the page runtime has already used — the Get restates what Rec already holds. Replace with a direct call against Rec (CheckAvailability(Rec)).

See sample: do-not-re-get-rec-inside-onaftergetrecord.bad.al.