0

I have an object in C# that I want to use as a primary key in a database that auto-increments when new objects are added. The object is basically a wrapper of a ulong value that uses some bits of the value for additional hints. I want to store it as a 'pure' ulong value in a database but I would like get an automatic conversion when the value is loaded / unloaded from DB. IE, apply the 'hint' bits to the value based on the table they come from.

I went on a journey of implementing my own IUserType object based on number of examples I found online ( tons of help on this forum ).

I have an ObjectId class that acts is an object ID

class ObjectIdType: IUserType
{
    private static readonly NHibernate.SqlTypes.SqlType[] SQL_TYPES = { NHibernateUtil.UInt64.SqlType };

    public NHibernate.SqlTypes.SqlType[] SqlTypes
    {
        get { return SQL_TYPES; }
    }

    public Type ReturnedType
    {
        get { return typeof(ObjectId); }
    }

    ...
}

I have a mapping class that looks like this:

public class ObjectTableMap()
{ 
    Id(x => x.Id)
    .Column("instance_id")
            .CustomType<ObjectIdType>()
            .GeneratedBy.Native();
}

At this point I get an exception at config that Id can only be an integer. I guess that makes sense but I was half expecting that having the custom type implemented, the native ulong database type would take over and work.

I've tried to go down the path of creating a custom generator but its still a bit out of my skill level so I am stumbling though it.

My question is, is it possible for me to accomplish what I am trying to do with the mapping?

1 Answers1

0

I think, it is not possible, because your mapping uses the native generator for the Id. This can only be used for integral types (and GUIDs). You can try to use assigned Ids with your custom type, so you are responsible for assigning the values to your Id property.

There is another alternative: Why not set your information bits on class level, instead depending on your table? Your entities represent the tables, so you should have the same information in your entity classes. Example:

class Entity
{
    protected virtual ulong InternalId { get; set; } // Mapped as Id

    public virtual ulong Id                          // This property is not mapped
    {
        get
        {
            var retVal = InternalId;
            // Flip your hint bits here based on class information
            return retVal;
        }
    }
}

You could also turn InternalId into a public property and make the setter protected.

rumpelstiefel
  • 466
  • 3
  • 5