Repository navigation
Add support for $count in navigation properties - #2051
Conversation
|
|
||
| if (this.lexer.CurrentToken.Text == UriQueryConstants.CountSegment && isSelect) | ||
| { | ||
| // $count in only allowed in $expand. e.g $expand=NavProperty/$count |
|
/// |
||
| /// This represents one level of expansion for a particular expansion tree. | ||
| /// | ||
| public sealed class ExpandedCountSelectItem : ExpandedReferenceSelectItem |
There was a problem hiding this comment.
Do you think it's better to derive from ExpandedReferenceSelectItem?
Or shall we have a base NavigationSelectItem, and others derived from it?
There was a problem hiding this comment.
The semantics are the same though.
Also, ExpandedNavigationSelectItem inherits from the ExpandedReferenceSelectItem
| /// A filter clause for this expand (can be null) | ||
| /// A search clause for this expand (can be null) | ||
|
/// |
||
| public ExpandedCountSelectItem(ODataExpandPath pathToNavigationProperty, IEdmNavigationSource navigationSource, FilterClause filterOption, SearchClause searchOption) |
There was a problem hiding this comment.
Only $filter and $search are allowed within nav/$count?
There was a problem hiding this comment.
Yes: From the protocol http://docs.oasis-open.org/odata/odata/v4.01/cs01/part1-protocol/odata-v4.01-cs01-part1-protocol.html#sec_RequestingtheNumberofItemsinaCollect
On success, the response body MUST contain the exact count of items matching the request after applying any $filter or $search system query options, formatted as a simple primitive integer value with media type text/plain. Clients SHOULD NOT combine the system query options $top, $skip, $orderby, $expand, and $format with the path suffix /$count. The result of such a request is undefined.
|
Looks good to me. |
|
@KenitoInc I cloned your branch and performed some tests based on the sample scenarios you provided in the PR description. Result: {
"@odata.context": "http://service/$metadata#Categories(Products())",
"value": [
{
"Id": "PG1",
"Name": "Food",
"Products": [
{
"Id": "P1",
"CategoryId": "PG1",
"Name": "Sugar",
"Color": "White",
"TaxRate": 0.06
},
{
"Id": "P2",
"CategoryId": "PG1",
"Name": "Coffee",
"Color": "Brown",
"TaxRate": 0.06
}
]
},
{
"Id": "PG2",
"Name": "Non-Food",
"Products": [
{
"Id": "P3",
"CategoryId": "PG2",
"Name": "Paper",
"Color": "White",
"TaxRate": 0.14
},
{
"Id": "P4",
"CategoryId": "PG2",
"Name": "Pencil",
"Color": "Black",
"TaxRate": 0.14
}
]
}
]
}Test 1: Result: {
"@odata.context": "http://service/$metadata#Categories(Products/$ref())",
"value": [
{
"Id": "PG1",
"Name": "Food",
"Products": [
{
"@odata.id": "Products('P1')"
},
{
"@odata.id": "Products('P2')"
}
]
},
{
"Id": "PG2",
"Name": "Non-Food",
"Products": [
{
"@odata.id": "Products('P3')"
},
{
"@odata.id": "Products('P4')"
}
]
}
]
}Test 2: Result: {
"@odata.context": "http://service/$metadata#Categories(Products/$ref())",
"value": [
{
"Id": "PG1",
"Name": "Food",
"Products": [
{
"@odata.id": "Products('P1')"
}
]
},
{
"Id": "PG2",
"Name": "Non-Food",
"Products": [
{
"@odata.id": "Products('P3')"
}
]
}
]
}Test 3: Result: {
"@odata.context": "http://service/$metadata#Categories(Products/$ref())",
"value": [
{
"Id": "PG1",
"Name": "Food",
"Products": [
{
"@odata.id": "Products('P1')"
},
{
"@odata.id": "Products('P2')"
}
]
},
{
"Id": "PG2",
"Name": "Non-Food",
"Products": [
{
"@odata.id": "Products('P3')"
},
{
"@odata.id": "Products('P4')"
}
]
}
]
}I don't know if I'm doing something wrong. Can you verify whether you get the expected results against a sample service? |
@gathogojr I have added this feature to OData Core. We will support it in WebApi later. |
argh... I jumped the gun without even realizing it! |
|
This PR has Quantification details
Why proper sizing of changes matters
Optimal pull request sizes drive a better predictable PR flow as they strike a
What can I do to optimize my changes
How to interpret the change counts in git diff output
Was this comment helpful? 👍 :ok_hand: :thumbsdown: (Email) |
| if (this.lexer.CurrentToken.Text.StartsWith("$", StringComparison.Ordinal) | ||
| && (!allowRef || this.lexer.CurrentToken.Text != UriQueryConstants.RefSegment) | ||
| && this.lexer.CurrentToken.Text != UriQueryConstants.CountSegment) |
There was a problem hiding this comment.
Could you explain the logic here?
There was a problem hiding this comment.
If Path segment starts with $, it should only have $count or $ref when allowRef is true
e.g
$expand=NavProp/$ref
$expand=NavProp/$count
|
/// |
||
| /// Create an Expand item using a nav prop, its entity set and a SelectExpandClause | ||
| /// | ||
| /// the path to the navigation property for this expand item, including any type segments | ||
| /// the navigation source for this ExpandItem | ||
| /// A filter clause for this expand (can be null) | ||
| /// A search clause for this expand (can be null) | ||
|
/// |
||
| public ExpandedCountSelectItem(ODataExpandPath pathToNavigationProperty, IEdmNavigationSource navigationSource, FilterClause filterOption, SearchClause searchOption) |
There was a problem hiding this comment.
I think it would be helpful if you could provide an concrete example of a path that this class represents, and how the parts of the path that the different parameters represent.
Issues
This pull request fixes issue #xxx.
Description
Add support for
$countin Navigation properties.We are adding a new
PathSelectItemnamedExpandedCountSelectItemwhich inherits fromExpandedReferenceSelectItem.The
ExpandedCountSelectItemonly supports 2 query options,$filterand$search. See spec http://docs.oasis-open.org/odata/odata/v4.01/cs01/part1-protocol/odata-v4.01-cs01-part1-protocol.html#sec_RequestingtheNumberofItemsinaCollectChecklist (Uncheck if it is not completed)
Additional work necessary
If documentation update is needed, please add "Docs Needed" label to the issue and provide details about the required document change in the issue.