IWebQueryable and DefaultWebQueryRepository

The IWebQueryable interface defines a repository which accepts an ODATA query as inputs and returns paged results:

public interface IWebQueryable
    Task<DataPage<D>> ExecuteQuery<D, Dext>(IWebQueryProvider query)
        where Dext: D;


Where the IWebQueryProvider object contains the ODATA query. It is available through dependency injection when the ODATA middleware is added. D is the data ViewModel whose properties are used in the ODATA query, and Dext a subclass of it with further properties that contains grouped values, that is returned in the paged results when the ODATA query contains groupings.

DefaultWebQueryRepository is the default implementation of IWebQueryable. It acts as a wrapper that adds the ExecuteQuery method to any existing ICRUDRepository. The ICRUDRepository to be wrapped is passed as the unique parameter of the DefaultWebQueryRepository constructor. Below an example that shows how to use DefaultWebQueryRepository

IWebQueryProvider queryProvider;
private IWebQueryable oDataRepository;
public GridTestController(
    Data.ApplicationDbContext db,
    IStringLocalizerFactory factory,
    IHttpContextAccessor accessor,
    IWebQueryProvider queryProvider) :base(factory, accessor)
    //in actual 3 layers applications repository inherit
    //from DefaultCRUDRepository
    //and then it is DI injected
    Repository = DefaultCRUDRepository.Create(db, db.Products);
    oDataRepository = new DefaultWebQueryRepository(Repository);
    this.queryProvider = queryProvider;
public async Task<IActionResult> IndexEditDA()
    queryProvider.OrderBy =
        queryProvider.OrderBy ?? "Name asc";
    queryProvider.Top = queryProvider.Top??"3";
    var query = queryProvider.Parse<ProductViewModel>();

    ProductlistViewModel model = new ProductlistViewModel
        Query = query,
        Products = await oDataRepository
            .ExecuteQuery<ProductViewModel, ProductViewModelGrouping>


    return View(model);

In case the query contains no sorting a default sorting must be added otherwise data cannot be paged and the call to the ExecuteQuery method results into an InvalidOperationException

The same argument applies to queryProvider.Top that defines the page size. Both instructions must preceed any other usage of queryProvider

Fork me on GitHub