Skip to content

OpenAccess – using a base class for identity and version

December 4, 2009

Hi all,

This blogpost will not be that long. It is just a note for my previous posts on building an WCF architecture using OpenAccess.

If you are lucky to start on a new system from scratch and you use Telerik OpenAccess as your ORM (if you don’t use it, give it a whirl, it’s amazing) you will probably use the forward mapping wizard. The wizard enables you to take plain C# classes (decorated with the Persistent attribute) and create or update a database schema according to your defined mapping (a default one is applied if you don’t define one).

Anyway, you might find it cumbersome to define the identity for each and every persistent class you have in your system. The latest project I worked on had 500+ of those. But since OpenAccess is a ORM it naturally supports inheritance and can map those accordingly. Ok, to set the scene I need a common base class for all my persistent class that will hold the id of the object and the version of the object (OpenAccess uses the latter for optismistic concurrency if you wish to use that feature – I did).

Ok, lets take a look at our base class:

    public abstract class BaseEntity
        protected int id;
        protected int version;

        public int Id
            get { return id; }

        public int Version
            get { return version; }
            set { version = value; }

Note: You can get the full solution including the source code for the base class from Teleriks Code Library.

The class is really simple. It is decorated with the Persistent attribute, includes protected fields and public properties for those fields. Note though, that since OpenAccess handles generation of new object identifiers (the id field) I only delcared a readonly property for the Id. Note also that the class is declared as abstract. Doing so will make sure that the class can never be instantiated directly. Let’s take a look at the forward mapping dialog for this class og how we define the mapping:

As you can see the inheritance strategy is set to Horizontal. That’s all 🙂
So, what does this mean to OpenAccess?
It will make OpenAccess treat this class as one that should never be mapped directly to a database table AND all descendants of this class (for example Customer class) will include the fields from the BaseEntity class. Ofcause it will include the fields you say, it is normal OOP procedure. Yes, but OpenAccess will also include the fields in the resulting table for the “table generating class”.
So far so good, let’s take a look at a possible descendant. Simple class I know, but it illustrates what goes on perfectly.

    [Telerik.OpenAccess.Persistent(IdentityField = "id", VersionField = "version")]
    public class BusinessPartner : BaseEntity
        private string name;

        public string Name
            get { return name; }
            set { name = value; }

Our BusinessPartner class inherits from the BaseEntity class. It is also decorated with the Persistent attribute, but as opposed to the BaseEntity, it also defines the IdentityField and VersionField parameters of the Persistent attribute. These parameters will instruct OpenAccess on how to find the identity field and the version field for the BusinessPartner class. This class is also the table generating class, so the class is mapped to table in the database. Let’s see how it is mapped in the forward mapping wizard:

As you can see the identity type is set to be Single field, the Id field is defined as BaseEntity.Id and the key generator is HIGHLOW. As this class descends from our BaseEntity it also knows the fields of the super class. I used the HIGHLOW generator in this example, but it could have been any that supports the int type (the type of my identity field).
As for the concurrency settings they are pretty straight forward. The mechanism used is By version and the field is the BaseEntity.version field.
Note that the readonly textbox called base class, shows that our base class is the BaseEntity one.

When you build the project (if you have UpdateDatabase=True in your project settings) or when you hit the Telerik menu: OpenAccess->Database operations->Create/Update database your database schema is etiher created or updated. Let’s look at the resulting schema for the BusinessPartner class:

As you can see, the fields from the BaseEntity class (id and version) is defined in the business_partner table along with the fields (only name here) from the BusinesPartner class itself. The BaseEntity class does not have a corresponding table since it is abstract.

Conclusion: Instead of defining the identity and version fields in each and every persistent class, you should really consider making a base class common to all persistent classes. This abstract base class then serves as a kind of “template” for the resulting tables for the subclasses.

Hope you found the post useful.

Next time, I will take you through the connection settings for this project…



Leave a Reply

Fill in your details below or click an icon to log in: Logo

You are commenting using your account. Log Out /  Change )

Google+ photo

You are commenting using your Google+ account. Log Out /  Change )

Twitter picture

You are commenting using your Twitter account. Log Out /  Change )

Facebook photo

You are commenting using your Facebook account. Log Out /  Change )


Connecting to %s

%d bloggers like this: