You signed in with another tab or window. Reload to refresh your session.You signed out in another tab or window. Reload to refresh your session.You switched accounts on another tab or window. Reload to refresh your session.Dismiss alert
Paging links are currently implemented in two ways:
If options.IncludeTotalResourceCount is enabled, we fetch COUNT(*) before retrieving the actual data. This enables the link renderer to know the total number of pages, so it can render the Next/Last links reliably.
If this option is not enabled, the link renderer cannot know the total number of pages, so it switches to best-effort mode. This means it never renders Last and renders Next only when the current page is full. Note this may result in a Next link to an empty page.
For secondary endpoints, we currently have no way to fetch COUNT(*), so the link renderer always uses best-effort mode. The reason is that our query composition layer does not support retrieving nested values that do not map into a resource object.
Example for secondary endpoint /blogs/1/articles?filter...:
varquery=frombloginDbContext.Blogswhereblog.Id==1selectnewBlog(Id=blog.Id,Articles=blog.Articles.Where(filter)// where to put the count?);varcount=?
There is no way to determine the total number of articles in the second example: query.Count() would always return 1. query.Single().Articles.Count() would fetch all articles first, then determine count in-memory (which is a no-go for large tables).
The proposed solution (to determine the total count on secondary endpoints) is to turn the query upside-down. By using the inverse of the relationship. So instead of using the relationship Blog.Articles, we use its inverse, which is Article.Blog.
Example for secondary endpoint /blogs/1/articles?filter...:
If the inverse relationship is unavailable, there's nothing we can do to improve the current behavior. By default, we use the underlying EF Core model to find the inverse.
If another data source is used, developers need to implement a custom IInverseNavigationResolver.
This proposal solely affects logic to determine the total resource count. The actual fetching of data remains as-is.
This proposal only applies to to-many relationships, so we'll need to tackle many-to-many relationships too.
This requires a resource service to use a repository for a different resource type. For example: ResourceService<Blog> delegates to ResourceRepository<Article>. We can use our existing IResourceRepositoryAccessor for that.
IResourceDefinition.OnApplyFilter must be called on the secondary resource type, possibly on the primary resource type too.
The text was updated successfully, but these errors were encountered:
Paging links are currently implemented in two ways:
options.IncludeTotalResourceCount
is enabled, we fetchCOUNT(*)
before retrieving the actual data. This enables the link renderer to know the total number of pages, so it can render the Next/Last links reliably.For secondary endpoints, we currently have no way to fetch
COUNT(*)
, so the link renderer always uses best-effort mode. The reason is that our query composition layer does not support retrieving nested values that do not map into a resource object.Example for primary endpoint
/articles?filter...
:Example for secondary endpoint
/blogs/1/articles?filter...
:There is no way to determine the total number of articles in the second example:
query.Count()
would always return 1.query.Single().Articles.Count()
would fetch all articles first, then determine count in-memory (which is a no-go for large tables).The proposed solution (to determine the total count on secondary endpoints) is to turn the query upside-down. By using the inverse of the relationship. So instead of using the relationship
Blog.Articles
, we use its inverse, which isArticle.Blog
.Example for secondary endpoint
/blogs/1/articles?filter...
:Notes:
IInverseNavigationResolver
.ResourceService<Blog>
delegates toResourceRepository<Article>
. We can use our existingIResourceRepositoryAccessor
for that.IResourceDefinition.OnApplyFilter
must be called on the secondary resource type, possibly on the primary resource type too.The text was updated successfully, but these errors were encountered: