Telerik blogs

Telerik OpenAccess ORM always implemented relations between entities as reference properties (you can have properties on the both ends, or just on the one you decide) and this was the only supported way until now. Starting from Q3 2009 release we also started to support relations that are based not on reference properties, but rather on properties that expose the foreign keys for the entities. This pattern proved to be very useful for Linq To Sql, despite the fact that it is considered a ‘bad practice’ in the OOP domain.
With the latest release of Telerik OpenAccess ORM we added support for this feature named “shared columns”. Now you can choose if you want only the foreign key or the reference properties, or both.
Some of you may ask, why we named the feature “shared columns”. The actual reason is that if you have an OpenAccess entity (say Order) that has both a reference property (say Customer) and a foreign key property (say CustomerID) in the mapping, they both reference (or in other words “share”) the CustomerID column from the Orders table in the database.

In order to configure your OpenAccess entities with shared columns you have two options:
1.    Using reverse mapping
After you start the reverse mapping wizard, you can control the shared columns mapping with the following options:
You can use the Options dialog to set globally if foreign key IDs will be generated or not:

Shared columns options

…or you can make per-field settings in the advanced view tab of the reverse mapping wizard, where you can choose to not generate a field for the specific foreign key ID:

Shared columns advanced field

…and you can also choose to remove a specific association property:

Shared columns advanced relation

2.    Using forward mapping
In the forward mapping wizard, in order to correctly configure a shared column you just have to make sure that the association property and the foreign key property map to the same data base column:

Shared columns forward association

Shared columns forward foreign id 

 

Now that you have shared columns in your OpenAccess entities, you can start using this new feature.
In order to test the behavior of the shared column feature we will try the some scenarios:

Create new objects:

Customer customer = new Customer();
Order order = new Order();

order.Customer = customer;

After executing this code the values of the foreign id properties are both equal to 0.
However, if we add these new objects to a OpenAccess scope both the foreign id and reference properties on both ends will be updated by Telerik OpenAccess ORM:

using(IObjectScope scope = ObjectScopeProvider1.GetNewObjectScope())
{
scope.Transaction.Begin();
scope.Add(customer);
scope.Transaction.Commit();
}
Set association property:
IObjectScope scope = ObjectScopeProvider1.GetNewObjectScope();
IList<Customer> customers = scope.Extent<Customer>().ToList();

Order order = new Order();
order.Date = DateTime.Now;
order.Customer = customers[0];

scope.Transaction.Begin();
scope.Add(order); //it is here, where the CustomerID foreign property is updated
scope.Transaction.Commit();

In the above code snippet we create a new order object and set the relation to an existing customer using the reference property. In order for the foreign id property to be updated this new order object must be added to an OpenAccess scope.

Set foreign id property to a valid value:

IObjectScope scope = ObjectScopeProvider1.GetNewObjectScope();
IList<Customer> customers = scope.Extent<Customer>().ToList();

Order order = new Order();
order.Date = DateTime.Now;
order.CustomerID = customers[0].ID;

scope.Transaction.Begin();
scope.Add(order);
scope.Transaction.Commit(); //it is here where the Customer reference property is updated

In the above code snippet we create a new order object and set the relation to an existing customer using the foreign id property. The value of the Customer reference property is updated when the new order object is committed.

Set foreign id property to an invalid value:

IObjectScope scope = ObjectScopeProvider1.GetNewObjectScope();
IList<Customer> customers = scope.Extent<Customer>().ToList();

Order order = new Order();
order.Date = DateTime.Now;
order.CustomerID = 10;

scope.Transaction.Begin();
scope.Add(order);
scope.Transaction.Commit(); //this passes without any errors if there is no foreign key constraint in the database

In the above code snippet we create a new order object and set the foreign id property to a value that does not correspond to a valid customer record in the database. If there is a foreign key constraint in the database the transaction commit call will fail and the changes will not be persisted to the database.

Change the value of the foreign id property of an existing order object:

IObjectScope scope = ObjectScopeProvider1.GetNewObjectScope();
IList<Customer> customers = scope.Extent<Customer>().ToList();

Order order = customers[0].Orders[0];

scope.Transaction.Begin();
order.CustomerID = customers[1].ID; //this is where the Customer reference property is changed
scope.Transaction.Commit();

In the above code snippet we fetch the customers from the database and change the customer for the first order of the first customer to the second customer using the CustomerID foreign id property. The value of the Customer reference property is updated right away. Note that the change happens inside of a transaction block.

I hope that this post was helpful and you now understand the shared columns feature of Telerik OpenAccess ORM.


Comments

Comments are disabled in preview mode.