question-mark
Stuck on an issue?

Lightrun Answers was designed to reduce the constant googling that comes with debugging 3rd party libraries. It collects links to all the places you might be looking at while hunting down a tough bug.

And, if you’re still stuck at the end, we’re happy to hop on a call to see how we can help out.

Optimization Proposal - Reusing the query of specification

See original GitHub issue

For pagination, i need to get the total number records before applying the pagination. So, i do not want the query rebuilt each time; for counting the total number of records and fetching the records for the current page. Thus, i designated the EfRepository.ListForPaging. What do you think about it?

public abstract class BaseSpecification<T> : ISpecification<T>
{
    public bool IsPagingEnabled { get; set; } // It is modifiable.
}

public class SpecificationEvaluator<T> where T : BaseEntity
{
  public static IQueryable<T> ApplyPaging(IQueryable<T> inputQuery, ISpecification<T> specification)
  {
      return inputQuery.Skip(specification.Skip).Take(specification.Take);
  }
}
public class EfRepository<T> : IRepository<T>, IAsyncRepository<T> where T : BaseEntity
{
  // TotalCount: Total count of records before paging applied.
  // List: List of records after paging applied.
  public (int totalCount, IEnumerable<T> list) ListForPaging(ISpecification<T> spec)
  {
      // Disable paging to get total count.
      spec.IsPagingEnabled = false;
      var query = ApplySpecification(spec);
      // Get count through query, not specification.
      var totalCount = query.Count();
      // Paging is applied to the existing query so rebuilding the query is eliminated.
      var list = SpecificationEvaluator<T>.ApplyPaging(query, spec).AsEnumerable();

      return (totalCount, list);
  }
}

Usage

var filterSpecification = new CategoryFilterPaginatedSpecification(pageIndex, itemsPerPage, queryConstraints);
var (filteredCount, list) = _categoryRepository.ListForPaging(filterSpecification);

Issue Analytics

  • State:closed
  • Created 4 years ago
  • Comments:7 (2 by maintainers)

github_iconTop GitHub Comments

2reactions
fisenicommented, Jul 16, 2019

I read your comments once again. Obviously, your concern is building the query twice, not the the round trip to DB. Building the query (as it is done here), is just an in-memory process, and won’t affect too much. But, in some super large apps yea it might have an impact. I got your point, I just have few notes

  • The method should be async (we should use .CountAsync() instead of Count()). The IRepository is not used anymore.
  • AsEnumerable() is a generic method for casting only. It’s OK, but if used upon IQueryable, then the query won’t be processed at that moment. Instead, it will happen at the caller side, and depending how the results are used, some unexpected errors might occur (e.g. if result is used directly to iterate in for, foreach…).
  • Built in tuples are available only in C# 7. I don’t know the audience of the project, but folks using VS 2015 might need additional customization in their environment.
1reaction
efleming18commented, Jul 25, 2019

@expressiveco I don’t see why that would be a problem in terms of general architecture or OOP! 😃

Read more comments on GitHub >

github_iconTop Results From Across the Web

Chapter 4. Query Performance Optimization
The server parses, preprocesses, and optimizes the SQL into a query execution plan. The query execution engine executes the plan by making calls...
Read more >
Leveraging Re-costing for Online Optimization of ...
Parametric query optimization (PQO) deals with the prob- lem of finding and reusing a relatively small number of plans that can achieve good...
Read more >
SQL Query Optimization and Tuning to Improve Performance
Looking for the best tips for server performance optimization and tuning SQL Server? Check our article and list of best SQL query ......
Read more >
Advanced Spring Data JPA - Specifications and Querydsl
We're using the meta-model classes introduced with JPA 2.0 and generated by the Annotation Processing API. The main problem with this code is ......
Read more >
Data dependencies for query optimization: a survey
In this process, query optimization is the task of finding an optimal (or at least very good) physical execution plan with respect to...
Read more >

github_iconTop Related Medium Post

No results found

github_iconTop Related StackOverflow Question

No results found

github_iconTroubleshoot Live Code

Lightrun enables developers to add logs, metrics and snapshots to live code - no restarts or redeploys required.
Start Free

github_iconTop Related Reddit Thread

No results found

github_iconTop Related Hackernoon Post

No results found

github_iconTop Related Tweet

No results found

github_iconTop Related Dev.to Post

No results found

github_iconTop Related Hashnode Post

No results found