This section explains and gives a practical example of how support of component navigation properties is implemented in Entity Developer for NHibernate.
Support of this functionality includes the possibility of detaching to a complex type for further reusability not only scalar entity properties but also navigation properties with subsequent customization of complete mapping at the level of private mapping of a certain property with type equal to complex type of a certain entity.
There are several ways of component navigation properties mapping in NHibernate:
• | Many-to-one; |
• | One-to-many; |
• | One-to-one; |
• | Many-to-many. |
In this section we will consider the most popular of them, i.e. many-to-one mapping of component navigation properties. We will not focus on one-to-many and one-to-one types of component navigation properties mapping, as these types of mapping are not very common, besides, their usage and customization have little difference from the example under consideration and so are quite comprehensible. Many-to-many mapping is considered in details in Support of Many-to-Many Mapping for Component Navigation Properties section.
Many-to-one mapping of component navigation properties
This type of mapping can be efficient in case there are several tables in the database referring to the same details table using a foreign key constraint, and also, possibly (but this is not a must), having some set of fields matching in meaning and structure. Or the same table contains several sets of fields or foreign keys similar in structure, describing respectively several data objects similar in structure (e.g. when the same table containing descriptions of companies includes several matching sets of fields representing addresses of head and shipping offices). Then, after creating a model, it makes sense to move the similar set of the corresponding scalar and navigation properties into a separate complex type, and replace every such set in entities with a property having type equal to complex type and an appropriate customization of private mapping for this property. Example:The database contains the Orders and Suppliers tables, which have a foreign key constraint with the Countries table. The Orders and Suppliers tables have the same fields containing address description, and also a foreign key column associated with the table containing country names with a foreign constraint. The tables diagram is as follows: We perform the following sequence of operations:
Before defining a complex type, the model looks as follows: We select the Address, City, Region, PostalCode properties and the Country navigation property of the Supplier entity which are used to describe address, drag and drop them into a separate complex type and call it ‘AddressType’; an association appears between this complex type and the Country class and from now on it is the AddressType complex type that contains the Country navigation property, and instead of the set of the moved fields the Supplier entity contains a property with the type equal to AddressType, let’s call it Address. The association between AddressType and the Country entity looks as follows: As can be seen from the Association editor dialog box, part of relation settings is in the association itself, for the many-to-one case there is also a default mapping for the foreign key column of an entity which will contain the property of the specified complex type, but if necessary, it can be changed to a custom one for a certain entity property. This will be shown in our example further in this article. Since we created the complex type on the basis of the Supplier entity properties set, custom mapping of these properties was defined for this entity automatically and looks as follows: Now it is necessary to delete the association between the Order and Country entities, and also delete the ShipAddress, ShipCity, ShipRegion, ShipPostalCode properties of the Order entity. Instead of these properties set, describing the ship owner’s company address, it is necessary to add one property with the name ‘ShipAddress’ and the type equal to AddressType. As the column names of the address description and foreign columns in the Order entity do not match with the default mapping of the AddressType complex type properties and the default mapping of the association foreign column, it is necessary to set custom mapping for the Order entity’s ShipAddress property to these columns as displayed below: As a result we have the following model: A property is generated in the AddressType class, containing a reference to the Country class, and the classes Order and Supplier in their turn both contain a property with type equal to AddressType, and these properties describe addresses of the shipping company and vendor respectively. The NHibernate model for Entity Developer created in this example can be downloaded here. |