$Count is not working with .NET Core and ODataQueryOptions
Nobody has claimed this yet.
- Dominant language
- C#
- Stars
- 505
- Forks
- 186
- PR merge metrics
- No merged PRs in 30d
Description
I am using Odata with .NET 5.0. Odata version is : (Microsoft.AspNetCore.OData\8.0.1)
$Count is not working in my each request.
http://localhost:33451/odata/Users?$count=true
http://localhost:33451/odata/Users?$skip=20&$top=10&$count=true
http://localhost:33451/odata/Users?$filter=Salary gt 20000 and Salary le 50000&$count=true
http://localhost:33451/odata/Users?$skip=20&$top=10&$filter=Salary gt 20000 and Salary le 50000&$count=true
I am using ODataQueryOptions without EnableQuery.
I also gone through to remove "ApiController" and [Route("[controller]")] but it was not working.
using Comman.TestData;
using Domain;
using Domain.BO;
using Domain.Service;
using Microsoft.AspNetCore.Http;
using Microsoft.AspNetCore.Mvc;
using Microsoft.AspNetCore.OData.Query;
using System;
using System.Collections.Generic;
using System.Linq;
using AspNetCoreOData.Helper;
namespace AspNetCoreOData.Controllers
{
// [ApiController]
// [Route("[controller]")]
public class UsersController : ControllerBase
{
private readonly IMapperSession session;
// 0. Decalare constant - 2000
private const int batchSize = 2000;
public UsersController(IMapperSession session)
{
this.session = session;
}
[HttpGet]
// [EnableQuery()]
public IQueryable<User> Get(ODataQueryOptions options)
{
// 1. Get all IQuerable<User> from dao.
var userList = session.Users;
// 2. Define Include/ExcludeIDs more than 5000
List<int> includeIdsList = TestData.GetIncludeExcludeIdList();
IQueryable<User> results = Enumerable.Empty<User>().AsQueryable();
for (int i = 0; i < includeIdsList.Count; i = i + batchSize)
{
// 3. Split Include/ ExcludeIds in batch(constant - options.count)
var items = includeIdsList.Skip(i).Take(batchSize).ToArray();
IQueryable<User> getGridData = IQuerableHelper.GetGridData(userList, items, null);
if (options.Filter != null)
{
// 4.Apply Filter with Include / ExcludeIds in loop of batch.count and total includeId/ ExcludeId
results = results.Concat((IQueryable<User>)options.Filter.ApplyTo(getGridData, new ODataQuerySettings()));
}
else
{
results = results.Concat(getGridData);
}
}
if (options.OrderBy != null)
{
results = options.OrderBy.ApplyTo(results); //perform sort
}
if (options.Skip != null)
{
results = options.Skip.ApplyTo(results, new ODataQuerySettings()); //perform skip
}
if (options.Top != null)
{
results = options.Top.ApplyTo(results, new ODataQuerySettings()); //perform take
}
return results;
}
}
}
public class Startup
{
public Startup(IConfiguration configuration)
{
Configuration = configuration;
}
public IConfiguration Configuration { get; }
// This method gets called by the runtime. Use this method to add services to the container.
public void ConfigureServices(IServiceCollection services)
{
var connStr = Configuration.GetConnectionString("DefaultConnection");
services.AddNHibernate(connStr);
//services.AddControllers()
// .AddOData(
// opt => opt.Select()
// .SkipToken()
// .SetMaxTop(100)
// .Count()
// .Filter()
// .AddRouteComponents("odata", GetEdmModel()));
services.AddControllers().AddOData(opt => opt.Select().Expand().Filter().OrderBy().SetMaxTop(null).SkipToken().Count().AddRouteComponents("odata", GetEdmModel()));
services.AddSwaggerGen(c =>
{
c.SwaggerDoc("v1", new OpenApiInfo { Title = "AspNetCoreOData", Version = "v1" });
});
// services.AddControllersWithViews();
}
IEdmModel GetEdmModel()
{
var odataBuilder = new ODataConventionModelBuilder();
odataBuilder.EntitySet<User>("Users");
odataBuilder.EntitySet<User>("Employee");
odataBuilder.EntitySet<WeatherForecast>(nameof(WeatherForecast));
return odataBuilder.GetEdmModel();
}
// This method gets called by the runtime. Use this method to configure the HTTP request pipeline.
public void Configure(IApplicationBuilder app, IWebHostEnvironment env)
{
if (env.IsDevelopment())
{
app.UseDeveloperExceptionPage();
app.UseSwagger();
app.UseSwaggerUI(c => c.SwaggerEndpoint("/swagger/v1/swagger.json", "AspNetCoreOData v1"));
}
app.UseRouting();
app.UseAuthorization();
app.UseEndpoints(endpoints =>
{
endpoints.MapControllers();
});
}
}
Request URL :
http://localhost:33451/odata/users?$skip=10&$top=10&$count=true
**Response : **
{
"@odata.context": "http://localhost:33451/odata/$metadata#Users",
"value": [
{
"UserID": 7238,
"FirstName": "adam",
"LastName": "adkins",
"Designation": "Business Administrator",
"Email": "adam@datenwerk.com",
"Mobile": "1342532785",
"Gender": "Female",
"Salary": 19144.00,
"CreatedAt": "2010-07-25T00:00:00+05:30"
},
{
"UserID": 7239,
"FirstName": "adolph",
"LastName": "adams",
"Designation": "Software Developer",
"Email": "adolph@datenwerk.com",
"Mobile": "0335938520",
"Gender": "Male",
"Salary": 35966.00,
"CreatedAt": "2010-04-15T00:00:00+05:30"
},
{
"UserID": 7240,
"FirstName": "Alpesh",
"LastName": "adkins",
"Designation": "Frontend Developer",
"Email": "Alpesh@datenwerk.com",
"Mobile": "0620974648",
"Gender": "Female",
"Salary": 23516.00,
"CreatedAt": "2012-02-26T00:00:00+05:30"
},
{
"UserID": 7241,
"FirstName": "abel",
"LastName": "acosta",
"Designation": "Technical Lead",
"Email": "abel@datenwerk.com",
"Mobile": "0000082508",
"Gender": "Female",
"Salary": 36391.00,
"CreatedAt": "2020-07-24T00:00:00+05:30"
},
{
"UserID": 7242,
"FirstName": "abe",
"LastName": "abbott",
"Designation": "Software Developer",
"Email": "abe@datenwerk.com",
"Mobile": "4621393553",
"Gender": "Male",
"Salary": 19025.00,
"CreatedAt": "2018-07-18T00:00:00+05:30"
},
{
"UserID": 7243,
"FirstName": "abby",
"LastName": "adams",
"Designation": "Manager",
"Email": "abby@datenwerk.com",
"Mobile": "3370941413",
"Gender": "Female",
"Salary": 11530.00,
"CreatedAt": "2011-02-20T00:00:00+05:30"
},
{
"UserID": 7244,
"FirstName": "adolfo",
"LastName": "adams",
"Designation": "Manager",
"Email": "adolfo@datenwerk.com",
"Mobile": "5541084362",
"Gender": "Female",
"Salary": 38385.00,
"CreatedAt": "2015-05-01T00:00:00+05:30"
},
{
"UserID": 7245,
"FirstName": "Maulik",
"LastName": "acosta",
"Designation": "QA",
"Email": "Maulik@datenwerk.com",
"Mobile": "0574550885",
"Gender": "Female",
"Salary": 10403.00,
"CreatedAt": "2020-05-01T00:00:00+05:30"
},
{
"UserID": 7246,
"FirstName": "adam",
"LastName": "acosta",
"Designation": "Software Developer",
"Email": "adam@datenwerk.com",
"Mobile": "0072052077",
"Gender": "Male",
"Salary": 36698.00,
"CreatedAt": "2015-03-14T00:00:00+05:30"
},
{
"UserID": 7247,
"FirstName": "Alpesh",
"LastName": "abbott",
"Designation": "Technical Lead",
"Email": "Alpesh@datenwerk.com",
"Mobile": "7722694832",
"Gender": "Male",
"Salary": 10209.00,
"CreatedAt": "2013-04-20T00:00:00+05:30"
}
]
}
Contributor guide
No contributing guide indexed for this repository
First steps
- Read the whole issue, then the project's contributing guide.
- Comment on the issue to say you are picking it up — it saves two people doing the same work.
- Fork the repository and make your change on a branch.
- Open a pull request that references the issue number.
Research direction
Start by reproducing the request against UsersController.Get in the attached sample and review the OData setup in Startup.ConfigureServices. Trace how ODataQueryOptions are applied for filter, skip, and top, and compare that path with the requested count behavior. Done means the response includes the expected count for the shown requests without breaking the other query options.
Written by the indexing model from the issue text.
Assessment
- Tech stack
- csharp
- Domain
- api, backend
- Issue type
- Bug
- Difficulty
- 4/5
- Estimated time
- 3-5 days
- Activity status
- Quiet
- Clarity
- Mostly clear
- Newbie friendliness
- 42/100