Account
Primary Contact
The LookupRecordContext component loads and provides editing access to the record referenced by a lookup field on the parent RecordContext. It inherits from BaseColumnEdit, so it binds to a column via the ColumnName parameter just like any other editor.
When you place a LookupRecordContext inside a RecordContext and specify a ColumnName that maps to a lookup field, the component automatically reads the lookup value from the parent record, retrieves the referenced record from Dataverse, and exposes it as a nested RecordContext. Any editors placed inside the LookupRecordContext bind to the looked-up record's fields.
The ColumnName parameter must refer to a lookup column on the parent record. The component uses this to resolve the target table and record ID.
{/* Edits inside <LookupRecordContext> bind to columns on the
LOOKED-UP record's table — the linked contact, not the account. */}
<RecordContext table="account" queryParameterName="id">
<LookupRecordContext columnName="primarycontactid">
<TextEdit columnName="firstname" />
<TextEdit columnName="lastname" />
<TextEdit columnName="emailaddress1" />
</LookupRecordContext>
</RecordContext><RecordContext TableName="account" QueryParameterName="id">
<LookupRecordContext ColumnName="primarycontactid">
<ColumnEdit ColumnName="firstname" />
<ColumnEdit ColumnName="lastname" />
<ColumnEdit ColumnName="emailaddress1" />
</LookupRecordContext>
</RecordContext>Like RecordContext, you can use the ContextTemplate parameter instead of ChildContent to access the looked-up TableRecord object directly in your markup.
{/* React has no <ContextTemplate> — read the LOOKED-UP record
inside a child component via `useRecordContext` (the lookup spawns its
own nested RecordContext, so this hook returns the contact, not the
account). */}
function PrimaryContactHeading() {
const { record } = useRecordContext();
const first = String(record?.['firstname']?.value ?? '');
const last = String(record?.['lastname']?.value ?? '');
return <h3>Primary Contact: {first} {last}</h3>;
}
<RecordContext table="account" queryParameterName="id">
<LookupRecordContext columnName="primarycontactid">
<PrimaryContactHeading />
<TextEdit columnName="emailaddress1" />
</LookupRecordContext>
</RecordContext><RecordContext TableName="account" QueryParameterName="id">
<LookupRecordContext ColumnName="primarycontactid">
<ContextTemplate>
<h3>Primary Contact: @context["firstname"] @context["lastname"]</h3>
<ColumnEdit ColumnName="emailaddress1" />
</ContextTemplate>
</LookupRecordContext>
</RecordContext>Changes made to fields within a LookupRecordContext are saved as part of the parent MainContext save operation. The OnBeforeSave callback can be used to run custom logic or cancel the save.
function MyPage() {
const onBeforeSave = async () => {
// Custom logic before saving the looked-up record.
// Throw to cancel the save.
};
return (
<MainContext>
<MenuBar>
<SaveContextButton />
<RefreshContextButton />
</MenuBar>
<RecordContext table="account" queryParameterName="id">
<TextEdit columnName="name" />
<LookupRecordContext
columnName="primarycontactid"
onBeforeSave={onBeforeSave}
>
<TextEdit columnName="firstname" />
<TextEdit columnName="lastname" />
</LookupRecordContext>
</RecordContext>
</MainContext>
);
}<MainContext>
<MenuBar>
<SaveContextButton />
<RefreshContextButton />
</MenuBar>
<RecordContext TableName="account" QueryParameterName="id">
<ColumnEdit ColumnName="name" />
<LookupRecordContext ColumnName="primarycontactid"
OnBeforeSave="OnBeforeSave">
<ColumnEdit ColumnName="firstname" />
<ColumnEdit ColumnName="lastname" />
</LookupRecordContext>
</RecordContext>
</MainContext>
@code {
private async Task OnBeforeSave(CancelEventArgs eventArgs)
{
// Custom logic before saving the looked-up record
}
}The RecordContext property provides access to the inner RecordContext for programmatic operations such as refreshing or checking dirty state.
{/* No outer ref handle — the React idiom is a child that reads
the nested context via `useRecordContext` and exposes whatever it needs
(here, a refresh button). The hook returns the LOOKED-UP record's
context, so `refresh()` reloads the contact, not the parent account. */}
function RefreshContactButton() {
const { refresh } = useRecordContext();
return <button onClick={() => refresh()}>Refresh contact</button>;
}
<LookupRecordContext columnName="primarycontactid">
<RefreshContactButton />
<TextEdit columnName="firstname" />
</LookupRecordContext><LookupRecordContext @ref="_lookupContext" ColumnName="primarycontactid">
<ColumnEdit ColumnName="firstname" />
</LookupRecordContext>
@code {
private LookupRecordContext _lookupContext;
private async Task RefreshContact()
{
await _lookupContext.RecordContext.RefreshAsync();
}
}The following example shows an account form that displays the primary contact's details inline using a LookupRecordContext bound to the primarycontactid lookup field.
Name | Type | Default | Description |
|---|---|---|---|
ChildContent | RenderFragment? | Child content of the component | |
ColumnName* | string | Column logical name to bind the editor to from the table record. | |
ContextTemplate | RenderFragment<TableRecord> | Render fragment that receives the loaded record for display or editing. | |
Description | string? | Description to be displayed in the tooltip. | |
Disabled | bool? | Should the editor be disabled. | |
DisplayLabelWhenAvailable | bool | True | Specifies whether to display a lable if available. |
DisplayTooltipWhenAvailable | bool | True | Specifies whether to display a tooltip if available. |
DisplayValidationErrorMessage | bool | True | Should a validation error message be displayed when the component fails validation? |
IsVisible | bool | True | Is the editor visible. |
Label | string? | Text to be displayed as a label for the editor. | |
ReadOnly | bool? | Should the editor be read-only. | |
RecordContext | RecordContext | Provides access to the inner LookupRecordContext.RecordContext for programmatic operations. | |
Required | bool? | Should the value be required. | |
Value | LookupValue? | The current lookup value (reference) managed by this context. |
ChildContentColumnName*ContextTemplateDescriptionDisabledDisplayLabelWhenAvailableDisplayTooltipWhenAvailableDisplayValidationErrorMessageIsVisibleLabelReadOnlyRecordContextLookupRecordContext.RecordContext for programmatic operations.RequiredValueName | Type | Description |
|---|---|---|
OnBeforeSave | EventCallback<CancelEventArgs> | Callback called before saving. Allows for cancelling the save operation. |
ValueChanged | EventCallback<ColumnValueBase> | Gets or sets a callback that updates the bound value. |
OnBeforeSaveValueChangedName | Parameters | Type | Description |
|---|---|---|---|
GetValidationErrors | List<string> | Returns a collection of the current validation errors. |
GetValidationErrors