Skip to content
Draft
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
33 changes: 27 additions & 6 deletions src/JsonApiDotNetCore/Services/JsonApiResourceService.cs
Original file line number Diff line number Diff line change
Expand Up @@ -62,7 +62,10 @@ public virtual async Task<IReadOnlyCollection<TResource>> GetAsync(CancellationT

using IDisposable _ = CodeTimingSessionManager.Current.Measure("Service - Get resources");

if (_options.IncludeTotalResourceCount)
QueryLayer queryLayer = _queryLayerComposer.ComposeFromConstraints(_request.PrimaryResourceType);
bool isPaginationDisabled = queryLayer.Pagination?.PageSize == null;

if (_options.IncludeTotalResourceCount && !isPaginationDisabled)
{
FilterExpression? topFilter = _queryLayerComposer.GetPrimaryFilterFromConstraints(_request.PrimaryResourceType);
_paginationContext.TotalResourceCount = await _repositoryAccessor.CountAsync(_request.PrimaryResourceType, topFilter, cancellationToken);
Expand All @@ -73,14 +76,18 @@ public virtual async Task<IReadOnlyCollection<TResource>> GetAsync(CancellationT
}
}

QueryLayer queryLayer = _queryLayerComposer.ComposeFromConstraints(_request.PrimaryResourceType);
IReadOnlyCollection<TResource> resources = await _repositoryAccessor.GetAsync<TResource>(queryLayer, cancellationToken);

if (queryLayer.Pagination?.PageSize?.Value == resources.Count)
{
_paginationContext.IsPageFull = true;
}

if (_options.IncludeTotalResourceCount && _paginationContext.TotalResourceCount == null)
{
_paginationContext.TotalResourceCount = resources.Count;
}

return resources;
}

Expand Down Expand Up @@ -112,15 +119,17 @@ public virtual async Task<TResource> GetAsync([DisallowNull] TId id, Cancellatio

using IDisposable _ = CodeTimingSessionManager.Current.Measure("Service - Get secondary resource(s)");

if (_options.IncludeTotalResourceCount && _request.IsCollection)
QueryLayer secondaryLayer = _queryLayerComposer.ComposeFromConstraints(_request.SecondaryResourceType!);
bool isPaginationDisabled = secondaryLayer.Pagination?.PageSize == null;

if (_options.IncludeTotalResourceCount && !isPaginationDisabled)
{
await RetrieveResourceCountForNonPrimaryEndpointAsync(id, (HasManyAttribute)_request.Relationship, cancellationToken);

// We cannot return early when _paginationContext.TotalResourceCount == 0, because we don't know whether
// the parent resource exists. In case the parent does not exist, an error is produced below.
}

QueryLayer secondaryLayer = _queryLayerComposer.ComposeFromConstraints(_request.SecondaryResourceType!);
QueryLayer primaryLayer = _queryLayerComposer.WrapLayerForSecondaryEndpoint(secondaryLayer, _request.PrimaryResourceType, id, _request.Relationship);
IReadOnlyCollection<TResource> primaryResources = await _repositoryAccessor.GetAsync<TResource>(primaryLayer, cancellationToken);

Expand All @@ -134,6 +143,11 @@ public virtual async Task<TResource> GetAsync([DisallowNull] TId id, Cancellatio
_paginationContext.IsPageFull = true;
}

if (_options.IncludeTotalResourceCount && _paginationContext.TotalResourceCount == null && rightValue is ICollection rightResourcesForCount)
{
_paginationContext.TotalResourceCount = rightResourcesForCount.Count;
}

return rightValue;
}

Expand All @@ -152,15 +166,17 @@ public virtual async Task<TResource> GetAsync([DisallowNull] TId id, Cancellatio

using IDisposable _ = CodeTimingSessionManager.Current.Measure("Service - Get relationship");

if (_options.IncludeTotalResourceCount && _request.IsCollection)
QueryLayer secondaryLayer = _queryLayerComposer.ComposeSecondaryLayerForRelationship(_request.SecondaryResourceType!);
bool isPaginationDisabled = secondaryLayer.Pagination?.PageSize == null;

if (_options.IncludeTotalResourceCount && !isPaginationDisabled)
{
await RetrieveResourceCountForNonPrimaryEndpointAsync(id, (HasManyAttribute)_request.Relationship, cancellationToken);

// We cannot return early when _paginationContext.TotalResourceCount == 0, because we don't know whether
// the parent resource exists. In case the parent does not exist, an error is produced below.
}

QueryLayer secondaryLayer = _queryLayerComposer.ComposeSecondaryLayerForRelationship(_request.SecondaryResourceType!);
QueryLayer primaryLayer = _queryLayerComposer.WrapLayerForSecondaryEndpoint(secondaryLayer, _request.PrimaryResourceType, id, _request.Relationship);
IReadOnlyCollection<TResource> primaryResources = await _repositoryAccessor.GetAsync<TResource>(primaryLayer, cancellationToken);

Expand All @@ -174,6 +190,11 @@ public virtual async Task<TResource> GetAsync([DisallowNull] TId id, Cancellatio
_paginationContext.IsPageFull = true;
}

if (_options.IncludeTotalResourceCount && _paginationContext.TotalResourceCount == null && rightValue is ICollection rightResourcesForCount)
{
_paginationContext.TotalResourceCount = rightResourcesForCount.Count;
}

return rightValue;
}

Expand Down
Loading