IWebQueryable and DefaultWebQueryRepository
        The IWebQueryable interface defines a repository which accepts an ODATA query as inputs
        and returns paged results:
    
{
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
    
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>
(queryProvider)
};
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