Has anyone implemented something similar, are there any big downsides to
this approach?
What ive done is implement an extension method off IQueryable which will
take the existing 'Paged' query (skip,take) and produce an additional query
for TotalRecordCount to be exec'd in a batch.
Of course, this does not need to be called if your not "Skip"ing records so
its up to the developer to know when to use this vs a direct query.ToList()
etc (without enhancement of the code below)
EXAMPLE QUERY:
var query = CreateQuery<HosTotals>(driverId, groupId, filter)
.Where(filter)
.Fetch(x => x.DriverBase)
.Fetch(x => x.TruckPCBase)
.Page(filter);
var result = Transact(() => query.Paginate(),
IsolationLevel.ReadUncommitted);
PAGINATION:
public class PagedResult<T> where T : Entities.Base.IEntity
{
public int RecordCount { get; private set; }
public List<T> Records { get; private set; }
private PagedResult(IQueryable<T> query)
{
var countExpression =
System.Linq.Expressions.Expression.Lambda(new
ExpressionVisitor_ForCountQuery().Visit(query.Expression));
var countQuery = new NhQueryable<T>(query.Provider,
countExpression.Body);
var count = countQuery.ToFutureValue(x => x.Count());
var results = query.ToFuture();
RecordCount = count.Value;
Records = results.ToList();
}
public static PagedResult<T> Paginate(IQueryable<T> query)
{
return new PagedResult<T>(query);
}
public static PagedResult<T> Paginate(IQueryable<T> query,
GridDataFilter filter)
{
return new PagedResult<T>(query.Page(filter));
}
}
public static IQueryable<T> Page<T>(this IQueryable<T> source,
GridDataFilter filter)
{
return source.Skip(filter.PageSize *
filter.Page).Take(filter.PageSize);
}
public class ExpressionVisitor_ForCountQuery : ExpressionVisitor
{
protected override Expression VisitMethodCall(MethodCallExpression
node)
{
if (node.Method.DeclaringType != typeof(Enumerable) &&
node.Method.DeclaringType != typeof(Queryable))
return base.VisitMethodCall(node);
if (node.Method.Name != "Skip"
&& node.Method.Name != "Take"
&& node.Method.Name != "OrderBy"
&& node.Method.Name != "OrderByDescending"
&& node.Method.Name != "ThenBy"
&& node.Method.Name != "ThenByDescending")
return base.VisitMethodCall(node);
//eliminate the method call from the expression tree by
returning the object of the call.
return base.Visit(node.Arguments[0]);
}
}
--
You received this message because you are subscribed to the Google Groups
"nhusers" group.
To unsubscribe from this group and stop receiving emails from it, send an email
to [email protected].
To post to this group, send email to [email protected].
Visit this group at https://groups.google.com/group/nhusers.
For more options, visit https://groups.google.com/d/optout.