Table of Contents

References and collections

The model of an application is usually divided into several entities representing the data structure of the application. These entities often have relationships with each other. In Neos, there are two ways to represent the relationship between two entities : references and collections.
A relationship can be configured on either of the involved entities. Whether you need to create a reference or a collection depends on the entity you are editing and the type of their relationship.

References

When an A entity depends on one instance of a B entity, then we can configure a reference on the A entity. This type of relationship is also referred to as one-to-one or many-to-one depending whether the referenced entity (B) can be referenced by only one or multiple instances of the A entity.

Examples of references that an Person entity (A) can have with other entities (B) :


In Neos Studio, configuring a reference on an entity is done in two steps.

[optional] Creating scalar properties to store the reference data

Note

If you do not perform this step, the scalar property will be automatically generated from the information entered in the reference (next step).

This step is to add one or several scalar properties on the A entity that will store the key that uniquely identifies the referenced entity (B).

In the case of the relationship between Person and Address, the auto-incremented integer ID property is the key that uniquely identifies each Person and Address. Therefore, to be able to reference an Address on a Person, we will need to add an integer AddressID property on the Person entity.

Had the key of the Address entity been composed of multiple properties, we would need to create the same amount of scalar properties on the Person entity to be able to reference an Address.

Configuring the reference with one-to-one relationship

This step is to configure the reference on the A entity. In Neos Studio, on the entity, use the button Add reference (one to one) to add it. Here we need to specify the referenced entity (B).

For the relationship between Person and Address, we will create an new reference on the Person entity and reference the Address entity.

After that, a navigation property must be configured by setting its name and mapping the scalar properties to store the reference data on the A entity. If the scalar properties were not created manually in the previous step, they will be automatically added when saving the reference. This navigation property will allow the access to the properties of the referenced entity (B) instance of an A entity instance.

In the case of the relationship between Person and Address, we can name the navigation property Address and map the AddressID property of the Person entity to Address.ID.

After generating the application, it will be possible to access the Street property of the Address of a Person using the following C# code.

string street = employee.Address.Street;
Warning

Due to performance concerns, data accessible through navigation properties is loaded by default. See article about EF Core Lazy loading.

Note

When the Address navigation property is loaded, both employee.AddressID and employee.Address.ID properties return the same value.

[optional] Configuring a collection navigation property on the referenced entity

In the case of many-to-one relations, it is possible to configure a collection that will automatically be generated on the referenced entity (B).

For example, when configuring the reference to a Company on a Person, we can create the collection in the entity Company with the name Employees. This will automatically generate a collection named Employees on the Company entity.

This collection will allow the access to the data of all the Persons that are employed by a Company using the following C# code.

string name = company.Employees.First().Name.
Note

The configuration of a collection on a reference is optional. If not done, the only drawback is that it will not be possible to access to the A entity from the referenced B one. For example, it will not be possible to access to the Employees from a Company entity, but accessing to a Company from a Person it employs will work just fine.

Collections (one-to-many relationship)

We saw that when configuring a one-to-many relationship on an entity , a reference can be created on the A entity. In Neos Studio, on the entity, use the Add reference (one to many) button to add it.But the relationship can also be configured from the B entity perspective. In this case, the relationship is viewed from a one-to-many point of view. Therefore, instead of configuring a reference on the A entity, we can choose to configure a collection on the B entity .

Example of the relationship between a Person (A) and a Company (B) from the Company perspective :

Creating a collection on the "one side" of a relationship (B) is equivalent to creating a reference with a **collection_ on the "many side" of the relationship (A). Therefore, the creation of a collection requires similar steps to the creation of a **reference__.

Creating scalar properties to store reference data on the "many side" entity

When a collection is created on a B entity, a reference will automatically be generated on the A entity. Therefore we need to create scalar properties on the A entity to store the reference data to the B entity as described previously.

In the case of the relationship between Company and Person, we will need to add an integer CompanyID property on the Person entity.

Once again, had the key of the Company entity been composed of multiple properties, we would need to create the same amount of scalar properties on the Person entity.

Configuring the collection

The second step is to create the collection on the B entity. This is done with the Add collection button. Here we need to specify the referenced entity (A) that it will be linked to.

For the relationship between Company and Person, we will create an new collection on the Company entity and reference the Person entity.

After that, a navigation property must be configured by setting its name. This navigation property will allow the access to all the A entity instances that reference a B entity instance.

In the case of the relationship between Company and Person, we can name the navigation property Employees.

After generating the application, it will be possible to access the Name property of one of the Employees of a Company using the following C# code.

string name = company.Employees.First().Name.
Warning

Due to performance concerns, data accessible through navigation properties is loaded by default. See article about EF Core Lazy loading.

Finally, we need to configure the reference that will automatically be generated on the referenced entity (A). First we must set its name, then we need to map the properties linked to the scalar properties of the referenced entity (A) that were created earlier to store the reference data. This navigation property will allow the access to the properties of the referenced entity (B) instance of an A entity instance.

For our example, we can call this reference Company and map the scalar property CompanyID.

After generating the application, it will be possible to access the Name property of one of the Company employing a Person using the following C# code.

string name = person.Company.Name.
Note

When the Company navigation property is loaded, both person.CompanyID and person.Company.ID properties return the same value.