Friday, 19 October 2007

Strongly-typed primary key identifiers

Often the primary keys for tables are integer types. One problem can occur when you accidentally use the OrderID when you really meant to use CustomerID. This bug can happen inside the database and it can also arise in your code data layer.

One solution for this at the code level is to create custom types (eg. OrderIdentifier and CustomerIdentifier) so that the compiler will throw an error if you try and assign or compare different types.

The down-side to this is that because Integers are value types, you can't just inherit from the Integer class. Instead you need to store the actual integer value inside the class and expose it through a property.

eg.

Public Class OrderIdentifier
 
 Private _value As Integer
 Public Property Value() As Integer
 Get
 Return _value
 End Get
 Set(ByVal Value As Integer)
 _value = Value
 End Set
 End Property
 
 Public Sub New()
 End Sub
 
 Public Sub New(ByVal value As Integer)
 Me.Value = value
 End Sub
 
End Class

I've also noticed that NHibernate doesn't like having custom types for primary keys, as it tries to use the System.Type.IsAssignableFrom method to see if it can convert an Integer to the OrderIdentifier object (which fails).

I'm not sure that there's a workaround for that, as I think it would require a class to inherit from the Int32 structure, which isn't possible.

1 comment:

Ayende Rahien said...

Take a look at IUserType, it handles this scenario