mxmissile
mxmissile

Reputation: 11673

NHibernate IUserType Query Generating "= null" Instead of "is null"

It's generating "= null" instead of "is null" when querying a property using an IUserType. Gist of the biz rule is a null value in the database == OrderStatus.InProcess. Is there a work around or am I just doing it wrong?

Here is my IUserType implementation:

public class OrderStatusTypeMapper2 : IUserType
{
    public  object NullSafeGet(IDataReader rs, string[] names, object owner)
    {
        var name = NHibernateUtil.String.NullSafeGet(rs, names[0]) as string;

        if (string.IsNullOrEmpty(name))
            return OrderStatus.InProcess;

        return (OrderStatus)Enum.Parse(typeof(OrderStatus), name);
    }

    public  void NullSafeSet(IDbCommand cmd, object value, int index)
    {
        if (value == null)
        {
            NHibernateUtil.String.NullSafeSet(cmd, null, index);
            return;
        }

        var status = (OrderStatus)value;

        if (status == OrderStatus.InProcess)
        {
            NHibernateUtil.String.NullSafeSet(cmd, null, index);
            return;
        }

        NHibernateUtil.String.NullSafeSet(cmd, status.ToString(), index);
    }

    public  SqlType[] SqlTypes
    {
        get { return new[] { NHibernateUtil.String.SqlType }; }
    }

    public new bool Equals(object x, object y)
    {
        if (ReferenceEquals(x, y))
        {
            return true;
        }

        if (x == null || y == null)
        {
            return false;
        }

        return x.Equals(y);
    }

    public int GetHashCode(object x)
    {
        return x.GetHashCode();
    }

    public object DeepCopy(object value)
    {
        return value;
    }

    public object Replace(object original, object target, object owner)
    {
        return original;
    }

    public object Assemble(object cached, object owner)
    {
        return DeepCopy(cached);
    }

    public object Disassemble(object value)
    {
        return DeepCopy(value);
    }

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

    public bool IsMutable
    {
        get { return false; }
    }
}

Mapped with:

 Map(x => x.Status).CustomType<OrderStatusTypeMapper2>();

And then my usage:

 var results = session.Query<Order>()
            .Where(x => x.Status == OrderStatus.InProcess);

 Console.WriteLine(results.Count());

Which generates:

select
    cast(count(*) as INT) as col_0_0_ 
from
    sales orderentit0_ 
where
    orderentit0_.Status=@p0;
@p0 = NULL [Type: String (4000)]

And finally the desired (or similar) output:

select
    cast(count(*) as INT) as col_0_0_ 
from
    sales orderentit0_ 
where
    orderentit0_.Status is null;

Upvotes: 1

Views: 735

Answers (1)

aeliusd
aeliusd

Reputation: 469

If what you're asking is, how do you check if the Status column is null, this should do the trick:

var results = session.QueryOver<Order>()
     .WhereRestrictionOn(x => x.Status).IsNull;

Nhibernate won't pick up on the fact that your're using null and thus won't rewrite the sql, you have to explicitly use WhereRestrictionOn()and IsNull.

Upvotes: 2

Related Questions