0

We have some old tables with legacy schemas that we find it hard to work with.

Is it possible to use NHibernate to transform some of this data into a nicer model?

For example we might have an integer status column that we want to break down into several properties.

Legacy status: 0 - Active, 1 - Inactive, 2 - TemporarilyInactive, 3 - etc

We'd want to have something like:

bool IsActive { get; set; }
Status Status { get; set; }

(where Status is an enum)

I know that we can use a protected field that can take the status and then define the getters for the extra properties to return the appropriate value based on the backing field, but I'm pretty sure that this will disable the ability to query based on these properties.

Through this however, we wouldn't be able to do queries such as .Query(p => p.IsActive) and get that translated to SQL such as where status = 0, right?

Is the only way through custom IUserTypes? If so, is there any helper framework that makes working with IUserType easier in order to achieve this?

How do other people handle this?

andreialecu
  • 3,639
  • 3
  • 28
  • 36

1 Answers1

0

You can create your own "enumeration" class.

public class Status
{
    //The numeric (legacy) code
    public int Code{ get;private set; }
    //The human readable name
    public string Name{ get; private set; }
    //If this status is an active status
    public bool IsActive { get; private set; }

    private Status(int aCode, string aName, bool anIsActive)
    {
        Code = aCode;
        Name = aName;
        IsActive = anIsActive;
    }

    public static Status ACTIVE = new Status(0, "Active");
    public static Status INACTIVE = new Status(1, "Inactive");
    //Other status here...
    private static Status[] STATUSES = {Active,Inactive,...};

    //Returns a status based on the passed in code
    public static Status GetByCode(int aCode)
    {
        return STATUSES.FirstOrDefault(aStatus => aStatus.Code == aCode);
    }
}

Then you can have NHibernate set a private variable with the legacy value and have a getter/setter that converts between the enumeration and the legacy value.

private int theLegacyStatus;  //This is the value that NHibernate sets
public Status
{
    get
    {
        return Status.GetStatusByCode(theLegacyStatus);
    }
    set
    {
        theLegacyStatus = value.Code;
    }
}

You can then use this enumeration in NHibernate queries: .Query(p => p.Status.Code)

brainimus
  • 10,586
  • 12
  • 42
  • 64
  • If NHibernate uses theLegacyStatus in the mapping, querying for p.Status.Code won't work. It doesn't know anything about the wrapping Status property so it can't be expected to know what SQL to generate for such a query. (already tried something like this and getting an exception like "could not resolve property: Status") – andreialecu Mar 10 '11 at 13:28
  • Are you using criteria? The way I use this method is `var criteria = DetachedCriteria.For.Add(Restrictions.Eq("theLegacyStatus"), 0);` which will return you all `ObjectType` objects where the status is Active (0). – brainimus Mar 10 '11 at 14:26
  • Yes, I know criteria or HQL would work, but that corrupts the model. You have to know about the innards of the entity in order to perform a query, which is bad design. I was looking for a better solution. Thanks for your answer though. – andreialecu Mar 10 '11 at 21:03