|
Article relates to
|
Telerik OpenAccess ORM
|
|
Created by
|
Ivailo Ivanov
|
|
Last modified
|
April 06, 2012
|
|
Last modified by
|
Pencho Popadiyn
|
DESCRIPTION
One To One relationships are frequently found in database models.
Telerik OpenAccess ORM is prepared to map such models, but not in a straight forward way – there is no 1:1 association currently available in the Domain Model.
There are generally two approaches for implementing this mapping –
using vertical inheritance or
using an One to Many relationship while manually maintaining some synchronization.
In this Knowledge Base article we will describe how this mapping can be achieved in different scenarios and provide examples for the approaches available.
SOLUTIONS
Take for example the following MS SQL database:
Here we have two tables,
CustomerMain and
CustomerDetail. There is a foreign key, defined in
CustomerDetail ID column, pointing to the
CustomerMain ID column. Depending on the scenario, the ID of
CustomerMain can be auto-calculated or manually inserted.
Mapping such a structure in a Domain Model can be achieved using one of the following approaches:
I. VERTICAL INHERITANCE (recommended)
With vertical inheritance, the data access will be straight forward – the association between the objects is maintained automatically and there is no need of manual code to support the approach.
In order to implement the inheritance, you need first to create the Domain Model and map it to a database. Depending on the scenario, you can create the model first or the database first.
A. In case of a forward mapping scenario you will have to implement a standard vertical inheritance between the two objects.
1) Create the the classes and the properties you need. In our example, we are going to have an integer primary key in the tables.
The ID of the parent object (CustomerMain) is set as a primary key (Identity = True) and the IdentityMechanism is “DatabaseServerCalculated”, meaning that Telerik OpenAccess ORM will expect the database server to generate the ID value during insert operations.
Note: The vertical inheritance approach is demonstrated with an auto-incremented identity, since this is the more complex case as a matter of relational mapping. When the primary key is manually maintained in the code, there will be no difference in the implementation.
2) Create an inheritance between the objects.

The class representing the source table for the foreign key should be the child in the inheritance. In our example that is CustomerDetail.
3) Set the inheritance of the child class to Vertical

4) Delete the ID property of the child class (
CustomerDetail) – it will implicitly use the ID of the parent class (
CustomerMain). The final model should look this this:
5) Create data tables matching the classes
6) Save the Domain Model
7) Apply the Domain Model to the database. Note that a foreign key will be created for the
CustomerDetail table, pointing to the
CustomerMain.
8) Set the identity calculation of the
CustomerMain ID column in the database
B. In case of a reverse mapping scenario, the approach is implemented in the following steps:
1) Update the relevant Domain Model classes from the database. By default, in case of One to One relationship, a One to Many association will be created in the model:

2) Delete the association
3) Add an inheritance between the classes, making sure that the class corresponding to the table that holds the foreign key is the child class.

4) Set the inheritance of the child class to Vertical
5) Set the Discriminator Value for the base class (CustomerMain) to {no}.

6) Delete the ID property of the child class (CustomerDetail) – it will implicitly use the ID of the parent class (CustomerMain)
7) Select the child class (CustomerDetail) and ensure that it is mapped to the corresponding table (in this example, to the CustomerDetails table)

8) Save the Domain Model
After the model is properly configured through the steps above, you are ready to begin using it. The relationship between the two classes will be maintained by
Telerik OpenAccess ORM.
In order to manipulate your data, you should have in mind that because of the inheritance, the fields of the parent object (
CustomerMain) will be visible and accessible through the child object (
CustomerDetails), but not vice versa. When you are manipulating a
CustomerDetails object,
CustomerMain table will be implicitly referred to when necessary. However, when you are using the
CustomerMain object, no automatic linkage will be available to the
CustomerDetails object.
Here is a short demonstration of CRUD operations on
CustomerDetails:
And here are the CRUD operations for
CustomerMain:
II. ONE TO MANY RELATIONSHIP
Another approach to the One to One relationship mapping is to model the link as one to many. That would still make use of some automation from
Telerik OpenAccess ORM, but as you will see below there will be some limitations that require custom code to be manually written in order to maintain the relation properly. For that reason this approach is not recommended and should be used only for the cases where the vertical inheritance cannot be utilized.
The main limitation of this modeling approach comes with the auto-generated identity fields. In case the foreign key field is auto-generated by the database, the operation for inserting a new pair of objects becomes more complex – it needs to be done in the following manner:
- Insert the object without a foreign key
- Retrieve the auto-generated primary key of the inserted row
- Insert the second object, the one with a foreign key, using the retrieved primary key of the first object
Those operations will not be performed by Telerik OpenAccess ORM automatically on SaveChanges() and should be coded by the user instead. For that reason we are going to present separate examples of the One to Many relationship approach – one for auto-generated primary key and one for manually maintained primary key.
A. Manually maintained primary key
For this scenario, consider that the primary key is GUID rather than an integer.
In case of reverse mapping, we will have the Domain Model generated by default without any intervention. As for the forward mapping, make sure the table with the foreign key constraint is the “one” in the One to Many relationship. The model will look like this:

In this case we have several things to take care of:
1) We need to make sure the primary keys are kept in sync. For simplicity I would suggest defining partial classes for both entities with an ID property:
2) The relationship needs to be maintained as One to One. A CustomerMain object should have only one CustomerDetail in its collection of CustomerDetails. One approach to help us maintain that is:
3) If we are using the child object (CustomerDetails), the insert approach is straight forward as in the vertical inheritance. Unfortunately that is not the case while working with CustomerMain - we would have to maintain the insertion sequence manually in the following manner:
4) If the cascading delete option is not enabled for the foreign key, the deletion of the object should be done separately, first for CustomerDetails and then for CustomerMain:
B. Auto-generated primary key
For this case let’s consider that the primary key is an auto-generated Int32 property.
The limitations of this approach are similar:
1) Keeping in sync the IDs of the object is important, but cannot be done with a property as in case A. Instead, after saving the parent object, we need to manually assign the same key to the child object
2) As for the case A, the relationship between the objects needs to be maintained as One to One. A CustomerMain object should have only one CustomerDetail in its collection of CustomerDetails. One approach to help us maintain that is:
3) Both for
CustomerDetail and for
CustomerMain the insert operation should be maintained by calling
SaveChanges() method for each of the objects:
4) As in case A, if the foreign key is without cascade delete option, the delete operation should be performed first for the CustomerMain and then for CustomerDetail:
Find below the demo C# and VB projects demonstrating all the described scenarios.
SUMMARY
One to One relationship is not directly supported in the Visual Designer, but can be modeled with
Telerik OpenAccess ORM in two different ways depending on the scenario. The one we recommend is through vertical inheritance, which requires the least manual efforts for maintaining the relationship. If inheritance is not suitable, you can also model the relation as One to Many and fill the gaps the approach introduces through some additional coding.