@@ -62,21 +62,26 @@ public virtual async Task<IReadOnlyCollection<TResource>> GetAsync(CancellationT
6262
6363 using IDisposable _ = CodeTimingSessionManager . Current . Measure ( "Service - Get resources" ) ;
6464
65- if ( _options . IncludeTotalResourceCount )
65+ QueryLayer queryLayer = _queryLayerComposer . ComposeFromConstraints ( _request . PrimaryResourceType ) ;
66+ int ? pageSize = queryLayer . Pagination ? . PageSize ? . Value ;
67+
68+ if ( _options . IncludeTotalResourceCount && pageSize != null )
6669 {
67- FilterExpression ? topFilter = _queryLayerComposer . GetPrimaryFilterFromConstraints ( _request . PrimaryResourceType ) ;
68- _paginationContext . TotalResourceCount = await _repositoryAccessor . CountAsync ( _request . PrimaryResourceType , topFilter , cancellationToken ) ;
70+ _paginationContext . TotalResourceCount = await _repositoryAccessor . CountAsync ( _request . PrimaryResourceType , queryLayer . Filter , cancellationToken ) ;
6971
7072 if ( _paginationContext . TotalResourceCount == 0 )
7173 {
7274 return Array . Empty < TResource > ( ) ;
7375 }
7476 }
7577
76- QueryLayer queryLayer = _queryLayerComposer . ComposeFromConstraints ( _request . PrimaryResourceType ) ;
7778 IReadOnlyCollection < TResource > resources = await _repositoryAccessor . GetAsync < TResource > ( queryLayer , cancellationToken ) ;
7879
79- if ( queryLayer . Pagination ? . PageSize ? . Value == resources . Count )
80+ if ( pageSize == null )
81+ {
82+ _paginationContext . TotalResourceCount = resources . Count ;
83+ }
84+ else if ( pageSize == resources . Count )
8085 {
8186 _paginationContext . IsPageFull = true ;
8287 }
@@ -107,31 +112,43 @@ public virtual async Task<TResource> GetAsync([DisallowNull] TId id, Cancellatio
107112 } ) ;
108113
109114 ArgumentNullException . ThrowIfNull ( relationshipName ) ;
110- AssertPrimaryResourceTypeInJsonApiRequestIsNotNull ( _request . PrimaryResourceType ) ;
111115 AssertHasRelationship ( _request . Relationship , relationshipName ) ;
116+ AssertPrimaryResourceTypeInJsonApiRequestIsNotNull ( _request . PrimaryResourceType ) ;
117+ AssertSecondaryResourceTypeInJsonApiRequestIsNotNull ( _request . SecondaryResourceType ) ;
112118
113119 using IDisposable _ = CodeTimingSessionManager . Current . Measure ( "Service - Get secondary resource(s)" ) ;
114120
115- if ( _options . IncludeTotalResourceCount && _request . IsCollection )
121+ QueryLayer secondaryLayer = _queryLayerComposer . ComposeFromConstraints ( _request . SecondaryResourceType ) ;
122+ QueryLayer primaryLayer = _queryLayerComposer . WrapLayerForSecondaryEndpoint ( secondaryLayer , _request . PrimaryResourceType , id , _request . Relationship ) ;
123+ int ? pageSize = secondaryLayer . Pagination ? . PageSize ? . Value ;
124+
125+ if ( _options . IncludeTotalResourceCount && _request . IsCollection && pageSize != null )
116126 {
117127 await RetrieveResourceCountForNonPrimaryEndpointAsync ( id , ( HasManyAttribute ) _request . Relationship , cancellationToken ) ;
118128
119129 // We cannot return early when _paginationContext.TotalResourceCount == 0, because we don't know whether
120130 // the parent resource exists. In case the parent does not exist, an error is produced below.
121131 }
122132
123- QueryLayer secondaryLayer = _queryLayerComposer . ComposeFromConstraints ( _request . SecondaryResourceType ! ) ;
124- QueryLayer primaryLayer = _queryLayerComposer . WrapLayerForSecondaryEndpoint ( secondaryLayer , _request . PrimaryResourceType , id , _request . Relationship ) ;
125133 IReadOnlyCollection < TResource > primaryResources = await _repositoryAccessor . GetAsync < TResource > ( primaryLayer , cancellationToken ) ;
126134
127135 TResource ? primaryResource = primaryResources . SingleOrDefault ( ) ;
128136 AssertPrimaryResourceExists ( primaryResource ) ;
129137
130138 object ? rightValue = _request . Relationship . GetValue ( primaryResource ) ;
131139
132- if ( rightValue is ICollection rightResources && secondaryLayer . Pagination ? . PageSize ? . Value == rightResources . Count )
140+ if ( rightValue is IEnumerable rightResources )
133141 {
134- _paginationContext . IsPageFull = true ;
142+ int resourceCount = CollectionConverter . Instance . GetCount ( rightResources ) ;
143+
144+ if ( pageSize == null )
145+ {
146+ _paginationContext . TotalResourceCount = resourceCount ;
147+ }
148+ else if ( pageSize == resourceCount )
149+ {
150+ _paginationContext . IsPageFull = true ;
151+ }
135152 }
136153
137154 return rightValue ;
@@ -147,31 +164,43 @@ public virtual async Task<TResource> GetAsync([DisallowNull] TId id, Cancellatio
147164 } ) ;
148165
149166 ArgumentNullException . ThrowIfNull ( relationshipName ) ;
150- AssertPrimaryResourceTypeInJsonApiRequestIsNotNull ( _request . PrimaryResourceType ) ;
151167 AssertHasRelationship ( _request . Relationship , relationshipName ) ;
168+ AssertPrimaryResourceTypeInJsonApiRequestIsNotNull ( _request . PrimaryResourceType ) ;
169+ AssertSecondaryResourceTypeInJsonApiRequestIsNotNull ( _request . SecondaryResourceType ) ;
152170
153171 using IDisposable _ = CodeTimingSessionManager . Current . Measure ( "Service - Get relationship" ) ;
154172
155- if ( _options . IncludeTotalResourceCount && _request . IsCollection )
173+ QueryLayer secondaryLayer = _queryLayerComposer . ComposeSecondaryLayerForRelationship ( _request . SecondaryResourceType ) ;
174+ QueryLayer primaryLayer = _queryLayerComposer . WrapLayerForSecondaryEndpoint ( secondaryLayer , _request . PrimaryResourceType , id , _request . Relationship ) ;
175+ int ? pageSize = secondaryLayer . Pagination ? . PageSize ? . Value ;
176+
177+ if ( _options . IncludeTotalResourceCount && _request . IsCollection && pageSize != null )
156178 {
157179 await RetrieveResourceCountForNonPrimaryEndpointAsync ( id , ( HasManyAttribute ) _request . Relationship , cancellationToken ) ;
158180
159181 // We cannot return early when _paginationContext.TotalResourceCount == 0, because we don't know whether
160182 // the parent resource exists. In case the parent does not exist, an error is produced below.
161183 }
162184
163- QueryLayer secondaryLayer = _queryLayerComposer . ComposeSecondaryLayerForRelationship ( _request . SecondaryResourceType ! ) ;
164- QueryLayer primaryLayer = _queryLayerComposer . WrapLayerForSecondaryEndpoint ( secondaryLayer , _request . PrimaryResourceType , id , _request . Relationship ) ;
165185 IReadOnlyCollection < TResource > primaryResources = await _repositoryAccessor . GetAsync < TResource > ( primaryLayer , cancellationToken ) ;
166186
167187 TResource ? primaryResource = primaryResources . SingleOrDefault ( ) ;
168188 AssertPrimaryResourceExists ( primaryResource ) ;
169189
170190 object ? rightValue = _request . Relationship . GetValue ( primaryResource ) ;
171191
172- if ( rightValue is ICollection rightResources && secondaryLayer . Pagination ? . PageSize ? . Value == rightResources . Count )
192+ if ( rightValue is IEnumerable rightResources )
173193 {
174- _paginationContext . IsPageFull = true ;
194+ int resourceCount = CollectionConverter . Instance . GetCount ( rightResources ) ;
195+
196+ if ( pageSize == null )
197+ {
198+ _paginationContext . TotalResourceCount = resourceCount ;
199+ }
200+ else if ( pageSize == resourceCount )
201+ {
202+ _paginationContext . IsPageFull = true ;
203+ }
175204 }
176205
177206 return rightValue ;
@@ -677,6 +706,16 @@ private void AssertPrimaryResourceTypeInJsonApiRequestIsNotNull([SysNotNull] Res
677706 }
678707 }
679708
709+ [ AssertionMethod ]
710+ private void AssertSecondaryResourceTypeInJsonApiRequestIsNotNull ( [ SysNotNull ] ResourceType ? resourceType )
711+ {
712+ if ( resourceType == null )
713+ {
714+ throw new InvalidOperationException (
715+ $ "Expected { nameof ( IJsonApiRequest ) } .{ nameof ( IJsonApiRequest . SecondaryResourceType ) } not to be null at this point.") ;
716+ }
717+ }
718+
680719 [ AssertionMethod ]
681720 private void AssertRelationshipInJsonApiRequestIsNotNull ( [ SysNotNull ] RelationshipAttribute ? relationship )
682721 {
0 commit comments