ProtectedallTrue when every cell's value is null/empty (such a field carries no signal).
ProtectedbuildBuilds the per-record cells for one field, flagging equality against column 0.
ProtectedbuildBuilds the per-field delta matrix from the loaded records. Column 0 is the reference (survivor candidate); every other cell is compared against it. Fields where every record's value is empty are dropped.
ProtectedbuildBuilds an OR-ed WHERE clause across all keys, e.g. "(ID='a') OR (ID='b')".
ProtectedbuildProduces a readable label: the name-field value when present, else the key string.
ProtectedbuildCorrelates each input key (by column index) with its loaded row and builds the per-record value maps. Missing rows yield a record with all-null values.
ProtectedbuildBuilds the field-name select list: PK fields + the compared fields (deduped).
ProtectedcompareOrders fields name-field first, then DefaultInView, then by Sequence/Name.
Loads the requested records and computes the field-delta matrix.
the entity, keys, and optional field include-list to compare
the server-side context user (REQUIRED for correct isolation)
Optionalprovider: IMetadataProvideroptional request-scoped metadata provider (multi-provider safety)
The lower-level comparison entry point: given an already-resolved EntityInfo (no by-name metadata lookup), load the keyed records and compute the field-delta matrix.
Callers that already hold the entity and a request-scoped RunView (e.g. the duplicate
detector) use this directly via RecordComparisonOptions.RunViewInstance, avoiding a
redundant metadata resolution. The by-name RecordComparisonEngine.CompareRecords
resolves the entity and delegates here.
the resolved entity to compare records within
the composite keys to compare (column 0 is the reference/survivor candidate)
OptionalcontextUser: UserInfothe server-side context user (thread for correct isolation)
Optionaloptions: RecordComparisonOptionsinclude-list, an injected RunView, and/or the request-scoped provider
ProtectederrorBuilds a failed-shape result.
ProtectedextractExtracts the compared-field values from a loaded row (null when row missing).
ProtectedfindFinds the loaded row whose primary-key values match the supplied composite key.
ProtectedisTrue when a field should participate in the comparison.
ProtectedisTrue for MemberJunction system/internal columns that should not be diffed.
ProtectedloadLoads the records via a single read-only RunView OR-ing every supplied key. Returns plain rows (ResultType 'simple') or null on failure.
Optionaloptions: RecordComparisonOptionsProtectednormalizeCoerces a loaded value into a comparable scalar; passes scalars through, else null.
ProtectedrowTrue when every PK value on the row equals the key's value (case-insensitive).
ProtectedselectResolves the set of fields to compare: the include-list (case-insensitive) when supplied, otherwise all non-PK, non-system fields. Sorted name-field → DefaultInView → Sequence.
OptionalincludeFields: string[]ProtectedvaluesCase-insensitive, trimmed equality used for both diff highlighting and PK matching.
Framework-agnostic engine that loads a set of records for one entity and computes a structured field-level delta between them.
This is the shared comparison primitive used by the LLM reasoning path (it feeds the "deltas" context to the reasoning provider) and, opportunistically, by the UI side-by-side comparison panel. It performs a read-only load (
RunViewwithResultType: 'simple'+ targetedFields) — it never mutates records.No Angular, no Router, no resolver coupling. Server-side: always thread
contextUserand (in multi-provider scenarios) the request-scopedprovider.