Skip to main content
.NET 6.0+

Reference Properties in XPO

  • 3 minutes to read

The example below illustrates how to implement Reference (Foreign Key, Complex Type) Properties in an XPO persistent class.

private ReferencedObject lookupReferencedObject;
// Displayed in a lookup control:
public ReferencedObject LookupReferencedObject {
    get { return lookupReferencedObject; }
    set { SetPropertyValue(nameof(LookupReferencedObject), ref lookupReferencedObject, value); }

private ExpandPropertiesObject expandPropertiesObject;
// Displayed in a set of editors. Each editor represents an individual property of the referenced object:
[Aggregated, ExpandObjectMembers(ExpandObjectMembers.Always)]
public ExpandPropertiesObject ExpandPropertiesObject {
    get { return expandPropertiesObject; }
    set { SetPropertyValue(nameof(ExpandPropertiesObject), ref expandPropertiesObject, value); }

private EmbeddedDetailViewObject embeddedDetailViewObject;
// Displayed in a Detail Property Editor that shows a referenced object's Detail View:
[Aggregated, EditorAlias(EditorAliases.DetailPropertyEditor), ExpandObjectMembers(ExpandObjectMembers.Never)]
public EmbeddedDetailViewObject EmbeddedDetailViewObject {
    get { return embeddedDetailViewObject; }
    set { SetPropertyValue(nameof(EmbeddedDetailViewObject), ref embeddedDetailViewObject, value); }

private PopupDetailViewObject popupDetailViewObject;
// Displayed in a button edit that invokes a referenced object's Detail View in a separate modal window:
[Aggregated, ExpandObjectMembers(ExpandObjectMembers.Never)]
public PopupDetailViewObject PopupDetailViewObject {
    get { return popupDetailViewObject; }
    set { SetPropertyValue(nameof(PopupDetailViewObject), ref popupDetailViewObject, value); }

If you use Detail Property Editor for a reference property, or apply ExpandObjectMembers attribute to a reference property, it is required to initialize such a property in the when a new parent object is created. Otherwise, the reference property’s fields will be read-only. The initialization should be done in the overridden AfterConstruction method the following way:

public override void AfterConstruction() {
    embeddedDetailViewObject = new EmbeddedDetailViewObject(Session);
See Also