Add TransferFields SkipFieldsNotMatchingType guidance (#133)
Some checks failed
Validate knowledge index / validate-index (push) Has been cancelled
Validate AL review fixtures / validate-review-fixtures (push) Has been cancelled
Validate frontmatter and structure / validate (push) Has been cancelled

* Add TransferFields SkipFieldsNotMatchingType guidance

* Update transferfields-skip-type-mismatch-can-drop-data.md

* Update transferfields-skip-type-mismatch-can-drop-data.good.al

* Move good sample reference under Best Practice

Aligns the article with the repo convention used by the sibling data-modeling files: the .good.al reference belongs under Best Practice and the .bad.al reference under Anti Pattern. Previously both pointers sat under Anti Pattern, leaving the good-sample reference orphaned in the wrong section.

Co-authored-by: Copilot App <223556219+Copilot@users.noreply.github.com>

Copilot-Session: 3c998c71-f30b-40f3-b714-87fafed505d8

---------

Co-authored-by: Jesper Schulz <jeschulz@microsoft.com>
Copilot-Session: 3c998c71-f30b-40f3-b714-87fafed505d8
This commit is contained in:
Yahya Touil 2026-08-24 08:54:37 +01:00 • committed by GitHub
parent 9203e3ce2b
commit 9fab60153f
No known key found for this signature in database
GPG key ID: B5690EEEBB952194
3 changed files with 140 additions and 0 deletions

View file

@ -0,0 +1,55 @@
table 50123 "Transfer Source Bad"
{
fields
{
field(1; "Entry No."; Integer)
{
DataClassification = CustomerContent;
}
field(2; "Reference"; Code[20])
{
DataClassification = CustomerContent;
}
}
keys
{
key(PK; "Entry No.")
{
Clustered = true;
}
}
}
table 50124 "Transfer Target Bad"
{
fields
{
field(1; "Entry No."; Integer)
{
DataClassification = CustomerContent;
}
field(2; "Reference"; Integer)
{
DataClassification = CustomerContent;
}
}
keys
{
key(PK; "Entry No.")
{
Clustered = true;
}
}
}
codeunit 50492 "TransferFields Bad"
{
procedure CopyData(Source: Record "Transfer Source Bad"; var Target: Record "Transfer Target Bad")
begin
Target.TransferFields(Source, true, true);
end;
}

View file

@ -0,0 +1,59 @@
table 50121 "Transfer Source"
{
fields
{
field(1; "Entry No."; Integer)
{
DataClassification = CustomerContent;
}
field(2; "Reference"; Code[20])
{
DataClassification = CustomerContent;
}
}
keys
{
key(PK; "Entry No.")
{
Clustered = true;
}
}
}
table 50122 "Transfer Target"
{
fields
{
field(1; "Entry No."; Integer)
{
DataClassification = CustomerContent;
}
field(2; "Reference"; Integer)
{
DataClassification = CustomerContent;
}
}
keys
{
key(PK; "Entry No.")
{
Clustered = true;
}
}
}
codeunit 50491 "TransferFields Good"
{
procedure CopyData(Source: Record "Transfer Source"; var Target: Record "Transfer Target")
var
ConvertedReference: Integer;
begin
Target."Entry No." := Source."Entry No.";
Evaluate(ConvertedReference, Source."Reference");
Target.Validate("Reference", ConvertedReference);
end;
}

View file

@ -0,0 +1,26 @@
---
bc-version: [16..]
domain: data-modeling
keywords: [transferfields, skipfieldsnotmatchingtype, type-mismatch, field-mapping, data-transfer]
technologies: [al]
countries: [w1]
application-area: [all]
---
# Do not use SkipFieldsNotMatchingType to hide required TransferFields mismatches
## Description
`Record.TransferFields` copies values between fields with matching field numbers. Without `SkipFieldsNotMatchingType` (or with it `false`), a type mismatch between two fields in the same extension raises a runtime error at the point of transfer. Setting `SkipFieldsNotMatchingType` to `true` removes that error: the field is skipped instead, and the rest of the transfer completes normally. The caller gets no indication that a field was not copied.
## Best Practice
Use `TransferFields(Source)` only when every field the destination requires, including primary key fields, is guaranteed to share a matching field number and type with the source; this form defaults `InitPrimaryKeyFields` to `true`. Fields with no matching field number, and fields whose types differ across extensions, are skipped regardless of `SkipFieldsNotMatchingType` — that parameter only governs same-extension type mismatches. If the destination depends on a field that falls into either case, map and validate it explicitly in code rather than relying on `TransferFields` to catch the gap. Use `SkipFieldsNotMatchingType = true` only when skipping same-extension type mismatches is an intentional, documented part of the transfer contract.
See sample: `transferfields-skip-type-mismatch-can-drop-data.good.al`.
## Anti Pattern
Using `TransferFields(Source, InitPrimaryKeyFields, true)` as a generic way to make two evolving table schemas transfer without errors, when the destination depends on every required source field being copied. A type change on either table can turn a previously transferred field into a silently skipped one without making the transfer itself fail.
See sample: `transferfields-skip-type-mismatch-can-drop-data.bad.al`.