3

DateTime を制限するための拡張メソッドを作成しようとしていますか? 財産。これは検索クエリ用であり、可能なすべての日付フィールドに対してこのコードを複製したくありません。

public static IQueryOver<T, T> WhereInOpenEndedDateRange<T>(this IQueryOver<T, T> query, 
    Expression<Func<object>> field, 
    DateTime? rangeFrom, 
    DateTime? rangeTo)
{
    if(rangeFrom.HasValue && rangeTo.HasValue)
    {
        query.WhereRestrictionOn(field).IsBetween(rangeFrom.Value).And(rangeTo.Value);
    }
    else if (rangeFrom.HasValue)
    {
        //query.Where(() => /* help */ >= rangeFrom.Value);
    }
    else if (rangeTo.HasValue)
    {
        //query.Where(() => /* help */ <= rangeTo.Value);
    }

    return query;
}

表現の基本的な側面が欠けていると思います。何らかの形式の Expression パラメータを渡して/* help */スポットで使用することは可能ですか?

ありがとう

アップデート

近づいてはいるが、それでもとても遠くに感じる...

else if (rangeFrom.HasValue)
{
    var lt = Expression.LessThanOrEqual(field, Expression.Constant(rangeFrom, typeof(DateTime?)));
    var b = Expression.Lambda<Func<bool>>(lt);
    query.Where(b);
}

Func<object>と比較するため、これは機能しませんDateTime?。元のプロパティ式を新しい式にマージしFunc<bool>、必要なビットを保持して NH QueryOver をそのまま維持するにはどうすればよいですか?

QueryOverRestrictionBuilder の NH ソースを見た後、私はやります

string propertyName = ExpressionProcessor.FindMemberExpression(field.Body)

そして、Criteria メソッドを使用して制限を構築します。

4

1 に答える 1

2

を使用してこれを行う方法がわかりませんでした

Expression<Func<bool>> 

署名ですが、これはとにかく DateTime?s のみであるため、追加した制限がどのように影響するかわかりません。

基本的に、送信するパラメーターと正確に一致する式 (例ではフィールド) が必要でした。つまり、x=>x.SomeNullableDateField です。「x」は、最初に使用したクエリのタイプです

session.QueryOver<YourClass>()

そのため、送信される式のタイプに含める必要がありました。また、使用してそのパラメーターを取得できませんでした

ParameterExpression param = expression.Parameters.Single() 

比較式の作成に使用します。

BinaryExpression を に変換しよExpression<Func<bool>>うとしていましたが、さらに一歩進めてExpression<Func<T, bool>>.

public static IQueryOver<T, T> WhereInOpenEndedDateRange<T>(this IQueryOver<T, T> query,
    Expression<Func<T, DateTime?>> expression,
    DateTime? rangeFrom,
    DateTime? rangeTo) where T : class
{
    // Lambda being sent in
    ParameterExpression param = expression.Parameters.Single();

    if(rangeFrom.HasValue && rangeTo.HasValue)
    {
        // GT Comparison
        var expressionGT =
            Expression.GreaterThanOrEqual(
                expression.Body,
                Expression.Constant(rangeFrom.Value, typeof(DateTime?)
            )
        );

        // LT Comparison
        var expressionLT =
            Expression.LessThanOrEqual(
                expression.Body,
                Expression.Constant(rangeTo.Value, typeof(DateTime?)
            )
        );

        query.Where(
               Expression.Lambda<Func<T, bool>>(expressionGT, param))
               .And(
               Expression.Lambda<Func<T, bool>>(expressionLT, param)
        );
    }
    else if(rangeFrom.HasValue)
    {
        // GT Comparison
        BinaryExpression expressionGT =
            Expression.GreaterThanOrEqual(
                expression.Body,
                Expression.Constant(rangeFrom.Value, typeof(DateTime?)
            )
        );

        // covert to lambda
        query.Where(Expression.Lambda<Func<T, bool>>(expressionGT, param));
    }
    else if(rangeTo.HasValue)
    {
        // LT Comparison
        BinaryExpression expressionLT =
            Expression.LessThanOrEqual(
                expression.Body,
                Expression.Constant(rangeTo.Value, typeof(DateTime?)
            )
        );

        query.Where(Expression.Lambda<Func<T, bool>>(expressionLT, param));
    }

    return query;

}

使用法

var test = session.QueryOver<MyPocoClass>()
            .WhereInOpenEndedDateRange(x=>x.SomeNullableDateField, DateTime.Now, null);
于 2011-05-24T12:56:24.390 に答える