Wednesday, September 14, 2005

NHibernate and .NET 2.0 Nullables

UPDATE: I screwed up on this post.  See a correction here.

NHibernate is an object persistence system, enabling you to bypass oodles of data access layer and SQL code, directly storing objects in a database.  It’s a pretty slick concept, and I’ve been fooling around with getting some business entities stored via NHibernate.

The first problem I’ve run into is .NET 2.0 Nullables.  The BEs I’m working on use Nullables for various members, and NHibernate was most vexed with them since NHibernate only works for the 1.1 Framework.  However, all’s not lost.  Thankfully there’s a potential answer.  NHibernateContrib is modeled much like nAntContrib — a spot for handy tools which haven’t made it into the “real” release yet.  One of the tools in that project is support for Nullables.  Whoopee.

Ooops.  Not so fast.  The Nullables in NHibernateContrib are a custom type.  The examples show changing your BE’s public properties to these custom types.  That’s not so cool since it scatters a custom type throughout your code.  I’d rather stick with the native .NET 2.0 types.

No problem.  I can encapsulate everything inside the BE without too much trouble.

Here’s what one of my properties looks like before the change:

public Nullable<int> PersonID

{

get { return _personID; }

set

{

if (value != null)

{

if (value < 0)

{

throw new ArgumentOutOfRangeException("value", value,

"ID value < 0");

}

}

_personID = value;

_isModified = true;

}

}

My test for checking null functionality looks like so:

[Test]

public void CheckNullIDInputs()

{

PersonEntity pEnt = new PersonEntity();

pEnt.PersonID = null;

Assert.AreEqual(0, Nullable.Compare(null, pEnt.PersonID));

}

I got the BE’s property changed, but it took a bit of extra work since the Nullable types from NHibernateContrib use NullableType.Default for returning a particular null, i.e. NullableBoolean.Default.

Here’s what the BE property code looks like after my edits, with all tests running green:

public Nullable<int> PersonID

{

get {

// return _personID wasn't working correctly without this

// HasValue test due to apparent issues with how the

// NullableInt32 type is handled when it's Default.

if (_personID.HasValue)

{

return (int?)_personID;

}

else

{

return null;

}

}

set

{

if (value != null)

{

if (value < 0)

{

throw new ArgumentOutOfRangeException("value", value,

"ID value < 0");

}

_personID = (NullableInt32)value;

}

else

{

_personID = NullableInt32.Default;

}

_isModified = true;

}

}

So now everything’s green and shiny with my BE tests.  Now to press on and see about getting them successfully in the database!

 

1 comment:

Jim Holmes said...

Note to self: figure out how the heck to paste in decent-looking code snippets. BlogJet just ain't handling it well by default. :(

Subscribe (RSS)

The Leadership Journey