如何在NHibernate Queryover where子句中执行String.IsNullOrEmpty()测试?

时间:2012-09-28 17:01:32

标签: nhibernate queryover

今天我遇到了一个情况,我们遗留数据库中的一个字段永远不会为空...是空的。

我对这个数据库使用NHibernate 3.2,受影响的查询是用QueryOver编写的。

我目前的查询是

    return Session
        .QueryOver<FacilityGroup>()
        .Where(fg => fg.Owner.Id == Token.OwnerId && 
                     fg.UserName == Token.UserName)
        .OrderBy(fg => fg.Code).Asc
        .TransformUsing(Transformers.DistinctRootEntity);

我希望它是这样的:

        return Session
            .QueryOver<FacilityGroup>()
            .Where(fg => fg.Owner.Id == Token.OwnerId && 
                         fg.UserName == Token.UserName && 
                         !string.IsNullOrEmpty(fg.Code))                
            .OrderBy(fg => fg.Code).Asc
            .TransformUsing(Transformers.DistinctRootEntity);

当我尝试这个时,我得到一个异常“无法识别的方法调用:System.String:Boolean IsNullOrEmpty(System.String)”

所以NHibernate无法翻译string.IsNullOrEmpty。很公平。但是当我尝试这个时

        return Session
            .QueryOver<FacilityGroup>()
            .Where(fg => fg.Owner.Id == Token.OwnerId && 
                         fg.UserName == Token.UserName && 
                         !(fg.Code == null || fg.Code.Trim() == "" ))
            .OrderBy(fg => fg.Code).Asc
            .TransformUsing(Transformers.DistinctRootEntity);

我从范围''引用了'Domain.Entities.FacilityGroup'类型的InvalidOperationException“变量'fg',但它未定义”

有什么想法吗?

1 个答案:

答案 0 :(得分:13)

好的......我想我太早问了这个问题。我找到了解决这个问题的方法。

我能做的是通过SQL函数投影从hql调用'trim'函数。我最终将其编写为IQueryOver Extention方法以保持其灵活性。如果有人需要,我会在这里发布。

public static class QueriesExtentions
{
    public static IQueryOver<E, F> WhereStringIsNotNullOrEmpty<E, F>(this IQueryOver<E, F> query, Expression<Func<E, object>> propExpression)
    {
        var prop = Projections.Property(propExpression);
        var criteria = Restrictions.Or(Restrictions.IsNull(prop), Restrictions.Eq(Projections.SqlFunction("trim", NHibernateUtil.String, prop), ""));
        return query.Where(Restrictions.Not(criteria));
    }
}

这里正在使用

    return Session
        .QueryOver<FacilityGroup>()
        .Where(fg => fg.Owner.Id == Token.OwnerId && fg.UserName == Token.UserName )
        .WhereStringIsNotNullOrEmpty(fg => fg.Code)
        .OrderBy(fg => fg.Code).Asc
        .TransformUsing(Transformers.DistinctRootEntity);