El problema principal es que la especificación OData v4 es un estándar en evolución, ya que muchas implementaciones manejan algunas solicitudes de manera diferente, ya sea porque el estándar ha cambiado o porque el estándar era difícil de implementar o el comportamiento sugerido en la especificación no se ajusta al resto. de las convenciones.
¿Por qué es esto? ¿Estoy entendiendo mal la documentación?
Entonces, su problema principal es que estaba leyendo la documentación incorrecta para la API que estaba consultando. Es importante reconocer que con cada implementación de un estándar depende del desarrollador elegir qué tan conformes con ese estándar son, por lo que debe leer la documentación que va específicamente con esa API.
Esta es la especificación en cuestión para OData v4:
4.8 Abordar el recuento de una colección
Para abordar el valor bruto del número de elementos en una colección, los clientes agregan / $ count a la ruta de recursos de la URL que identifica el conjunto de entidades o la colección.
Los /$count
ruta sufijo identifica el recuento de número entero de registros de la recolección y no se debe combinar con las opciones de consulta del sistema $top
, $skip
, $orderby
, $expand
, y $format
. El recuento no deben verse afectadas por $top
, $skip
, $orderby
, o $expand
. El recuento se calcula después de aplicar los /$filter
segmentos de ruta $filter
o las $search
opciones de consulta del sistema a la colección.
En la implementación de .Net, dado que $count
es el resultado de una consulta, debe evaluarse como parte de la canalización de opciones de consulta, no como parte de la ruta.
Opciones de consulta de MS OData: recuento
La $count
opción de consulta del sistema permite a los clientes solicitar un recuento de los recursos coincidentes incluidos con los recursos en la respuesta. La opción de consulta $ count tiene un valor booleano de verdadero o falso.
Ejemplos:
- Devuelve, junto con los resultados, el número total de productos de la colección.
http://host/service/Products?$count=true
- El recuento de entidades relacionadas se puede solicitar especificando la
$count
opción de consulta dentro de la $expand
cláusula.http://host/service/Categories?$expand=Products($count=true)
Desde el punto de vista de la implementación, mezclar esta opción de consulta en la ruta rompe la convención utilizada para todos los demás procesamientos y análisis de URL, realmente es la extraña. ruta y consulta.
Respecto a la respuesta del objeto
En la implementación de .Net, debido a que $count
es compatible con expansiones de colecciones, así como en la raíz (ver el segundo ejemplo), han optado por inyectar el valor como metadatos / atributos mezclados con los resultados. De esa manera, la respuesta seguirá siendo válida para fines de serialización y el comportamiento del recuento volverá a ser coherente donde sea que se utilice.
Este último ejemplo lo dejo de una de mis propias API, demostrando la respuesta de atributo para colecciones expandidas, si $count=true
no devolviera el gráfico de objeto, no podría llegar a los recuentos de las expansiones en absoluto:
https://localhost/OData/Residents?$count=true&$expand=Entity($select=Id;$expand=Contacts($count=true;$top=0))&$select=id&$top=2
{
"@odata.context": "https://localhost/odata/$metadata#Residents(Id,Entity(Id,Contacts()))", "@odata.count": 29, "value": [ { "Id": 13110, "Entity": { "Id": 13110, "[email protected]": 6, "Contacts": [] } }, { "Id": 13164, "Entity": { "Id": 13164, "[email protected]": 6, "Contacts": [] } } ], "@odata.nextLink": "localhost/OData/Residents?$expand=Entity%28%24select%3DId%3B%24expand%3DContacts%28%24count%3Dtrue%3B%24top%3D0%29%29&$select=id&$top=2&$skip=2"
}