NHibernate IUserType查询生成“= null”而不是“is null”

时间:2016-01-25 16:43:04

标签: nhibernate fluent-nhibernate

使用"= null"查询属性时,它会生成"is null"而不是IUserType。 biz规则的要点是数据库中的空值== OrderStatus.InProcess。有没有解决方法,或者我做错了吗?

以下是我的IUserType实施:

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; }
    }
}

映射:

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

然后我的用法:

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

 Console.WriteLine(results.Count());

生成:

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

最后是期望的(或类似的)输出:

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

1 个答案:

答案 0 :(得分:2)

如果您要问的是,如何检查Status列是否为空,这应该可以解决问题:

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

Nhibernate没有意识到你正在使用null因此不会重写sql,你必须明确使用WhereRestrictionOn()和{{ 1}}。