views:

33

answers:

2

Does anyone know of a quick way to have NHibernate insert default values for value types as null into the database?

For example:

public class Foo
{
    public int SomeProperty { get; set; }
}

By default, int is 0. When it goes into the database, I would like it to go in as null. I know I could do this by changing SomeProperty to a nullable int, but perhaps there is another way? I also know that I could do this with an IUserType but is there an easy way of building a user type that can be generically used for all value types?

+2  A: 

This is not a simple way to make NHibe convert 0 to null and vice-versa, but an alternative suggestion (maybe or maybe not right in your situation).

Imo, using a default value to mean null is an antipattern; maybe you agree. I take it that you're trying to hook up some legacy code with a proper database; is that correct?

If you are in control of the business class which you are mapping (class Foo), then I recommend exposing a nullable version of SomeProperty for use moving forward:

public class Foo
{
    /// for new code, and for mapping to the database:
    public int? SomeProperty_new {get;set;}

    /// for legacy code only.  Eventually, refactor legacy code to use SomeProperty_new instead, and just remove this needless property.
    [Obsolete("This uses default value to mean null.  Use SomeProperty_new instead.")]
    public int SomeProperty_old
    { 
        get 
        {
            if (SomeProperty_new == null)
                return 0;
            else
                return SomeProperty_new;
        }
        set { /* convert from 0 to null if necessary and set to SomeProperty_new.*/ }
    }
}

You'll want better names than SomeProperty_new and SomeProperty_old, though.

On the other hand, if 0 is never a valid value (except to mean null), you could instead make the DB use a non-nullable value. It really depends on the situation at hand.

apollodude217
Thanks, I didn't think of using a backing field. In my case I should be able to tell NHibernate to use the backing field rather than the public property, which means I can still just expose one public property.You're right this is an anti-pattern; I just have a weird case where it might be the easiest way forward... also just asking out of curiosity.
cbp
simplified: return SomeProperty_new ?? 0; Nullable<TValueType> also has helper methods you could use like so:if (!SomeProperty_new.HasValue) return 0;else return SomeProperty_new.Value;orreturn SomeProperty_new.HasValue ? SomeProperty_new.Value : 0;
Martin R-L
+1  A: 

You could use NHibernate event architecture and plug a Listener doing the conversion on load, save or update.

Pascal Thivent
We do this for strings only, for value types we use nullable types.
Jamie Ide