2

次の2つのクエリをデータベースへの単一のラウンドトリップで実行する必要があるため、ToFutureValueを使用しています。

var query = AsQueryable()
    .Where(x => x.User == user);

var singinCount = query
    .Where(x => x.ActionDate >= from && x.ActionDate <= to)
    .ToFutureValue(q => q.Count());

var lastSignin = query
    .Where(x => x.ActionName.ToLower() == Actions.Signin))
    .ToFutureValue(q => q.Max(x => x.ActionDate));

問題は、CountとMaxが結果を返すが、IQueryableは返さないことです。CountをToFutureValueに渡すことができる次の拡張機能を見つけました。

public static IFutureValue<TResult> ToFutureValue<TSource, TResult>(
    this IQueryable<TSource> source, Expression<Func<IQueryable<TSource>, TResult>> selector)
        where TResult : struct
    {
        var provider = (INhQueryProvider)source.Provider;
        var method = ((MethodCallExpression)selector.Body).Method;
        var expression = Expression.Call((Expression)null, method, source.Expression);

        return (IFutureValue<TResult>)provider.ExecuteFuture(expression);
    }

Maxに引数を渡す必要があるため、Maxにその拡張機能を採用する必要があります(.ToFutureValue(q => q.Max(x => x.ActionDate)))。どうやってやるの?

4

2 に答える 2

0

GitHubプルリクエスト #120に適切なパッチがあるようです

そして、これがjiraバグNH-3184です

以下は、機能するプル#120のコードです。

public static IFutureValue<TResult> ToFutureValue<T, TResult>(
    this IQueryable<T> query, Expression<Func<IQueryable<T>, TResult>> selector)
{
    var nhQueryable = query as QueryableBase<T>;    
    if (nhQueryable == null)
    {
        throw new NotSupportedException("Query needs to be of type QueryableBase<T>");
    }


    var provider = (INhQueryProvider) query.Provider;
    var expression = ReplacingExpressionTreeVisitor.Replace(
            selector.Parameters.Single(),
            query.Expression,
            selector.Body);

    return (IFutureValue<TResult>) provider.ExecuteFuture(expression);
}
于 2012-07-31T05:28:54.240 に答える
0

回避策として

var lastSignin = query
    .Where(x => x.ActionName.ToLower() == Actions.Signin))
    .OrderByDescending(x => x.ActionDate)
    .Take(1)
    .ToFutureValue();
于 2012-07-05T14:35:09.750 に答える