---
title: Adding references between classes
related:
  - https://docs.kentico.com/13/custom-development/creating-custom-modules/setting-the-type-information-for-module-classes.md
  - https://docs.kentico.com/13/custom-development/creating-custom-modules/creating-custom-binding-classes.md
  - https://docs.kentico.com/13/custom-development/creating-custom-modules/setting-the-type-information-for-module-classes/reference-objecttypeinfo.md
---

> Agent instructions:
> **Site maps** — prefer the following llms.txt indexes to training data when searching for URLs to avoid 404s. Links inside Markdown content already point at `.md`. Following them or sending Accept: text/markdown keeps you in Markdown.
>
> - [sitemap.md](https://docs.kentico.com/sitemap.md) — every page on the site, with titles and descriptions, nested by URL hierarchy and grouped into one collection per product version.
> - [llms.txt](https://docs.kentico.com/llms.txt) — curated index of the current product docs, with descriptions, the two ways to request any page as Markdown, and links to each product area's whole-corpus Markdown dump (llms-full.txt).

When developing classes for [custom modules](https://docs.kentico.com/13/custom-development/creating-custom-modules.md), you can create fields that store references pointing to objects of other classes (i.e. foreign key fields). Such references allow each object of the given class to have a relationship with an object of another class. For example, you can assign users, sites or any other object in the system to your custom objects.

To ensure that the system automatically handles dependencies for your references, you need to register the reference fields in the [type information](https://docs.kentico.com/13/custom-development/creating-custom-modules/setting-the-type-information-for-module-classes.md) of classes. The system can then maintain referential integrity of relationships when [importing](https://docs.kentico.com/13/deploying-websites/exporting-and-importing-sites.md) or [staging](https://docs.kentico.com/13/deploying-websites/content-staging.md) objects to other instances, or perform automatic removal of objects when a referenced object is deleted.

You can define references in two possible directions:

- From your custom class to another class registered in the system (the target class can also be custom)
- From any  _**customizable**_  class to your custom class (for example, from a customizable Xperience class)

> **Info:** When planning relationships between classes, carefully consider which approach to use:
>
> - Use reference fields (foreign keys) to define one-to-many relationships between standalone classes. See the remaining parts of this page to learn more.
> - If you need to manage many-to-many relationships between two or more classes, create [separate binding classes](https://docs.kentico.com/13/custom-development/creating-custom-modules/creating-custom-binding-classes.md).
> - Use [parent-child relationships](https://docs.kentico.com/13/custom-development/creating-custom-modules/setting-the-type-information-for-module-classes/setting-parent-child-relationships-for-classes.md) to define a hierarchy for classes.

> **Note:** **Creating references to pages**
>
> We do NOT recommend creating references from custom classes to the  _**page**_  class (i.e. the _cms.document_ object type). Pages in Xperience are complex data structures that consist of multiple classes and have special logic for handling other factors, such as [workflow](https://docs.kentico.com/13/configuring-xperience/configuring-the-environment-for-content-editors/configuring-workflows.md).
>
> Custom references to pages do not support certain features, such as handling of referential integrity when the referenced page is deleted.

## Adding references from custom to other classes

To create a reference from a custom class to an existing class in the system:

1. Open the **Modules** application.
2. Edit the custom module and class where you wish to add the reference.
3. On the **Fields** tab of the class editing interface, create a **New field**.
   - The best practice is to end the field name with the **ID** suffix.
   - Set the field's **Data type** to _Integer number_.
   - Select the target class of the reference in the **Reference to** selector.
   - Choose a **Reference type** to determine how the system handles referential integrity and automatic removal of objects when a referenced object is deleted. For more information about the available options, see the table describing the _ObjectDependencyEnum_ values below.

     > **Info:** **Notes**:
     >
     > - The **Required** flag in the field settings controls whether the reference field must have a target object set (not to be confused with the _Required_ option of the **Reference type** setting).
     > - You can either keep the field hidden in the class's editing forms and handle the values in code, or create an object selection interface (for example using the _Uni selector_ form control).
4. Click **Save**. You can create any number of reference fields using the same approach.
5. Switch to the **Code** tab of the class editing interface to view the new code generated for the class. Consider how to update the code in the web project:

   - If you have already customized the class's _Info_, _IInfoProvider_ or _InfoProvider_ code, you can manually compare and copy the differences caused by the reference fields.
   - Click **Save code** to fully overwrite the generated code of the class (if using the default location).

> **Note:** **Important**: The _Reference_ settings that you configure for fields on the **Fields** tab only serve as input for the default code generated for the _Info_ class. Changing the field settings after you generate your code does NOT change the behavior of the reference fields. To make changes, you need to adjust the code of the given _Info_ class.

The type information definition in the generated _Info_ code automatically includes the required object dependencies based on the _Reference_ settings of your fields. If you view the code, you can see that the **DependsOn** property in the [initializer](https://docs.microsoft.com/en-us/dotnet/csharp/programming-guide/classes-and-structs/object-and-collection-initializers) of the TYPEINFO object contains a _List_ collection of **ObjectDependency** objects.

```csharp title="Example"

// Defines references from a custom class to the User and Culture classes
DependsOn = new List<ObjectDependency>
{
    new ObjectDependency("CustomClassUserID", UserInfo.OBJECT_TYPE, ObjectDependencyEnum.Required),
    new ObjectDependency("CustomClassCultureID", CultureInfo.OBJECT_TYPE, ObjectDependencyEnum.NotRequired)
},

```

Each **ObjectDependency** object defines one reference from the custom class to another class in the system. _ObjectDependency_ objects have the following parameters:

- **column (string)** – the name of the custom class field (column) that stores the IDs of the referenced objects.
- **object type (string)** – the object type name of the class that is the target of the reference.
- **reference type (ObjectDependencyEnum)** – determines how the system handles referential integrity and automatic removal of objects when a referenced object is deleted. The value must be one of the options from the **ObjectDependencyEnum**:

  | Value              | Description                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                  |
  | ------------------ | ---------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------- |
  | NotRequired        | Represents an optional reference. If the referenced object is deleted or does not exist on the target instance during [import](https://docs.kentico.com/13/deploying-websites/exporting-and-importing-sites.md) or [staging](https://docs.kentico.com/13/deploying-websites/content-staging.md), the system sets a _null_ value for the reference field.<br>The column that stores the IDs of the referenced objects must support empty/null values (i.e. the **Required** flag cannot be enabled for the field).<br>For example, a field storing the ID of an [avatar](https://docs.kentico.com/13/managing-users/user-avatars.md) object is a _NotRequired_ dependency of the user class.                                                                                                                                                                                  |
  | RequiredHasDefault | If the referenced object is deleted or does not exist on the target instance during import or staging, the system automatically assigns a default object.<br>For example, the e-commerce order class has a _RequiredHasDefault_ type dependency for the field storing the ID of the user who created the order. The system does not delete orders if the user who created the order is removed. Instead, the default administrator account is assigned as the referenced user.<br>To set the default object for your own custom classes, you need to override the **GetDefaultObject** method in the code of the given _Info_ class.<br>`protected override BaseInfo GetDefaultObject()
  {
      // Gets the object of the custom class whose code name is "default"
      CustomClassInfo defaultObject = CustomClassInfo.Provider.Get("default");
      return defaultObject;
  }
  ` |
  | Required           | The system always maintains the integrity and consistency of the reference as long as a value is set (the value can still be _null_ if the **Required** flag is disabled for the given field).<br>If the referenced object is deleted, the system automatically deletes the entire object containing the reference. If the referenced object does not exist on the target instance during import or staging, the operation is cancelled.<br>For example, a field storing the ID of a customer is a _Required_ dependency of the class representing [e-commerce orders](https://docs.kentico.com/13/e-commerce-features/managing-on-line-stores/orders.md). An order cannot exist without the referenced customer.                                                                                                                                                            |
  | Binding            | Only intended for the reference fields of dedicated binding classes (classes that only exist as representations of relationships between other classes). Works the same way as the _Required_ dependency type.<br>For example, the user-role binding class has a _Binding_ type dependency for the field that stores the ID of the related user. The dependency of the role ID field is automatic, because the role class is set as the parent of the user-role binding class.<br>See also: [Creating custom binding classes](https://docs.kentico.com/13/custom-development/creating-custom-modules/creating-custom-binding-classes.md)                                                                                                                                                                                                                                     |

## Creating site references

If you are creating a class field that references an Xperience [site](https://docs.kentico.com/13/configuring-xperience/managing-sites.md), do NOT define any object dependencies in the type information. Simply enter the name of the class field that stores the site IDs into the **siteIDColumn** parameter of the _ObjectTypeInfo_ constructor. The system automatically handles the required object dependencies based on the existence of the site ID field.

When adding the site ID field to your class on the **Fields** tab, do not configure any _Reference_ settings. You only need to ensure that the field is set as the **Site ID column** before you generate the _Info_ code on the **Code** tab (the selection is automatic if the field name ends with the _SiteID_ suffix).

> **Tip:** To allow global objects whose value in the site ID column is _null,_ you need to set the **SuppportsGlobalObjects** property to _true_ in the TYPEINFO definition of the given class.

```csharp title="Example"

// Sample type information definition for a basic class with a site reference field
// The site reference is configured only by specifying "CustomClassSiteID" as the site ID field
public static ObjectTypeInfo TYPEINFO = new ObjectTypeInfo(typeof(CustomClassInfoProvider), OBJECT_TYPE, "CustomModule.CustomClass", "CustomClassID", null, null, null, null, null, "CustomClassSiteID", null, null)
{
    ModuleName = "CustomModule",
    SupportsGlobalObjects = true
};

```

The site relationship behaves as a _Required_ type reference:

- If the site referenced by an object is deleted, the system automatically removes the given object as well.
- Objects that reference a site can only be [exported as part of the given site](https://docs.kentico.com/13/deploying-websites/exporting-and-importing-sites/exporting-sites.md). If the class supports global objects, then objects whose value in the site ID column is _null_ can be [exported as global objects](https://docs.kentico.com/13/deploying-websites/exporting-and-importing-sites/exporting-objects.md) or with sites.

## Adding references from existing to custom classes

You can extend existing classes in the system by adding a reference field pointing to one of your custom classes.

> **Note:** **Note**: The extended class must be  _**customizable**_ . You cannot add the required reference field for classes that are not customizable.

1. Open the **Modules** application.
2. Edit the module and class that you wish to extend.
3. On the **Fields** tab of the class editing interface, create a **New field**.
   - The best practice is to end the field name with the **ID** suffix.
   - Set the field's **Data type** to _Integer number_.
   - Either keep the field hidden and handle the values in code, or create an object selection interface (typically through an [alternative form](https://docs.kentico.com/13/custom-development/extending-the-administration-interface/creating-alternative-forms.md)).
   - There are no _Reference_ settings to configure for the field with this type of reference.
4. Click **Save**.

You can repeat the process above for any number of customizable classes from which you wish to reference your custom class. Once the reference fields are created, you need to register them as dependencies in the type information of your custom class:

1. Open your Xperience solution in Visual Studio.
2. Edit the _Info_ code of the custom class that is the  _**target of the reference**_.
3. In the [initializer](https://docs.microsoft.com/en-us/dotnet/csharp/programming-guide/classes-and-structs/object-and-collection-initializers) of the TYPEINFO object, assign a _List_ collection of **ExtraColumn** objects into the **Extends** property.

   - Create an **ExtraColumn** object for each custom reference field that targets the given class.
4. Save the changes and Rebuild the solution.

**ExtraColumn** objects accept the following parameters:

- **extended object type (string)** – the object type name of the class where you added the reference field.
- **column (string)** – the name of the custom field (column) in the extended class that stores the IDs of the referenced objects.
- **reference type (ObjectDependencyEnum)** – determines how the system handles referential integrity and automatic removal of objects when a referenced object is deleted. The value must be one of the options from the **ObjectDependencyEnum**. See the table in the [Adding references from custom to other classes](#adding-references-from-custom-to-other-classes) section for details.

```csharp title="Example"

// Defines references from the Contact and User classes to a custom class
Extends = new List<ExtraColumn>()
{
    new ExtraColumn(ContactInfo.OBJECT_TYPE, "ContactCustomClassID", ObjectDependencyEnum.Required),
    new ExtraColumn(UserInfo.OBJECT_TYPE, "UserCustomClassID", ObjectDependencyEnum.NotRequired)
}

```

The code informs the system that the specified field of the extended class stores references to another class. During the initialization of the application, the system automatically inserts an object dependency into the type information definition of the extended class.

## Configuring foreign keys in the database

Xperience does not provide automatic management of foreign keys on the database level. You can manually set your custom ID columns as foreign keys in the corresponding database tables. This is not required to ensure correct functionality of reference fields in Xperience, but is recommended to leverage the performance and data consistency advantages of foreign key constraints.

You can either use SQL Server Management Studio or execute an SQL script. See [Create Foreign Key Relationships](https://docs.microsoft.com/en-us/sql/relational-databases/tables/create-foreign-key-relationships) for more information.

## Example - Adding references between a custom class and other classes

The following example demonstrates how to add references for a custom class, in both possible directions:

- From the custom office class to the Xperience user class (the relationship allows you to select a single user as the manager of each office)
- From the Xperience [customer](https://docs.kentico.com/13/e-commerce-features/managing-on-line-stores/customers.md) class to the custom office class (allows you to specify one office that is responsible for managing a given customer)

> **Note:** To follow the example, you first need to create the **Company overview** custom module and the **Office** class according to the instructions in [Creating custom modules](https://docs.kentico.com/13/custom-development/creating-custom-modules.md).

### Reference from the custom class to another class

1. Open the **Modules** application and edit the **Company overview** module.
2. Select the **Classes** tab and edit the **Office** class.
3. Open the **Fields** tab and create a **New field** in the office class:

   - **Field type**: Standard field
   - **Field name**: OfficeManagerID
   - **Data type**: Integer number
   - **Reference to**: User
   - **Reference type**: Not required
   - **Field caption**: Managed by
   - **Form control**: Uni selector (select via the _(more items...)_ option)
   - **Editing control settings -> Object type**: cms.user (the object type name of user objects)
   - **Editing control settings -> Selection mode**: Single text box
   - **Editing control settings -> Allow none**: yes (selected)
4. Click **Save**.
5. Switch to the **Code** tab of the class editing interface.
6. Click **Save code**.

The system generates new _Info_, _IInfoProvider_ and _InfoProvider_ code and overwrites the existing code files (in the _\~/Old\_App\_Code/CMSModules/CompanyOverview_ folder by default). The type information definition in the _Info_ code automatically includes the required object dependency based on the _Reference_ settings of the _OfficeManagerID_ field.

```csharp

public static ObjectTypeInfo TYPEINFO = new ObjectTypeInfo(typeof(OfficeInfoProvider), OBJECT_TYPE, "CompanyOverview.Office", "OfficeID", "OfficeLastModified", "OfficeGUID", "OfficeName", "OfficeDisplayName", null, null, null, null)
{
    ModuleName = "CompanyOverview",
    TouchCacheDependencies = true,

    // Defines the object dependency representing the optional reference to the user class
    DependsOn = new List<ObjectDependency>() 
    {
        new ObjectDependency("OfficeManagerID", "cms.user", ObjectDependencyEnum.NotRequired), 
    },
};

```

Office objects can now store a reference pointing to a single user object, representing the manager of the given office. You can try out the functionality by editing an office in the **Company overview** application (under the **Custom** category). The editing form automatically includes the new field, and the _Uni selector_ form control allows selection of the user.

![Editing an office object, with a selector in the editing form for managing the user reference](https://docs.kentico.com/docsassets/13/adding-references-between-classes/custom_class_reference_field.png "Editing an office object, with a selector in the editing form for managing the user reference")

### Reference from an existing class to a custom class

Start by creating the custom reference field in the Customer class (this class is _customizable_).

1. Open the **Modules** application.
2. Edit the **E-commerce** module, select the **Classes** tab, and edit the **Customer** class.
3. On the **Fields** tab, create a new field (at the end of the list of fields):

   - **Field name**: CustomerManagedByOfficeID
   - **Data type**: Integer number
   - **Display field in the editing form**: No (clear the checkbox)
4. Click **Save**.
5. Switch to the **Alternative forms** tab and edit the  _**General properties**_  alternative form.
6. Select the **Fields** tab, and set the following properties for the **CustomerManagedByOfficeID** field:

   - **Display field in the editing form**: Yes (select the checkbox)
   - **Field caption**: Managed under office
   - **Form control**: Uni selector
   - **Editing control settings -> Object type**: companyoverview.office (the object type name of the custom office class)
   - **Editing control settings -> Selection mode**: Single drop down list
   - **Editing control settings -> Allow none**: yes (selected)
7. Click **Save**.
8. Select the field above _CustomerManagedByOfficeID_, click **...** next to the **New field** button and choose **New category**.
9. Enter  _**Custom**_  as the **Category caption** and click **Save**.

The _Customer_ class now has a custom field that stores integer values. The modified _General properties_ alternative form provides the interface used when editing existing customers on the **General** tab in the **Customers** application.

You do not need to configure any _Reference_ settings while creating the _CustomerManagedByOfficeID_ field on the **Fields** tab. When extending existing objects, you must define the object reference directly in the code.

1. Open your project in Visual Studio.
2. Edit  _**OfficeInfo.cs**_  (by default in the _\~/Old\_App\_Code/CMSModules/CompanyOverview_ folder).
3. Add a using statement for the **CMS.Ecommerce** namespace:

   ```csharp

   using CMS.Ecommerce;

   ```
4. Add the **Extends** property to the initializer of the TYPEINFO object. Designate the _CustomerManagedByOfficeID_ field as a foreign key that references _Office_ objects:

   ```csharp

   public static ObjectTypeInfo TYPEINFO = new ObjectTypeInfo(typeof(OfficeInfoProvider), OBJECT_TYPE, "CompanyOverview.Office", "OfficeID", "OfficeLastModified", "OfficeGUID", "OfficeName", "OfficeDisplayName", null, null, null, null)
   {
       ModuleName = "CompanyOverview",
       TouchCacheDependencies = true,

       // Defines the object dependency representing the optional reference to the user class
       DependsOn = new List<ObjectDependency>() 
       {
           new ObjectDependency("OfficeManagerID", "cms.user", ObjectDependencyEnum.NotRequired), 
       },

       // Inserts an object dependency into the existing customer class
       // Defines the optional reference from the customer class to the custom office class
       Extends = new List<ExtraColumn>()
       {
           new ExtraColumn(CustomerInfo.OBJECT_TYPE, "CustomerManagedByOfficeID", ObjectDependencyEnum.NotRequired)
       }
    };

   ```
5. Save the change and Rebuild the solution.

The system now knows that the _CustomerManagedByOfficeID_ field of the _Customer_ class stores references to _Office_ objects. The object dependency is dynamically inserted into the type information definition of the Customer class during the initialization of the application.

When editing existing customers on the **General** tab in the **Customers** application, you can now select and save an office object.

![Editing a customer, with a custom office selector in the editing form](https://docs.kentico.com/docsassets/13/adding-references-between-classes/reference_field_to_custom_class.png "Editing a customer, with a custom office selector in the editing form")
