6

今日、空であってはならない従来のデータベースのフィールドが空だったという状況に遭遇しました。

このデータベースに対して 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);

InvalidOperationException 「スコープから参照されるタイプ 'Domain.Entities.FacilityGroup' の変数 'fg' が、定義されていません」 が発生します

何かご意見は?

4

1 に答える 1

14

わかりました... この質問をするのが早すぎたと思います。私はこれを回避する方法を考え出しました。

私ができたのは、SQL Function Projection を介して 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);
于 2012-09-28T18:52:21.137 に答える