Skip to content

#1799 - CAML queries with Joins/ProjectedFields do not return projected fields - add CSOM-based GetItems support. Closes #1799 - #1802

Merged
Adam-it merged 4 commits into
pnp:devfrom
jeppesc11:dev
Aug 9, 2026
Merged

#1799 - CAML queries with Joins/ProjectedFields do not return projected fields - add CSOM-based GetItems support. Closes #1799#1802
Adam-it merged 4 commits into
pnp:devfrom
jeppesc11:dev

Conversation

@jeppesc11

@jeppesc11 jeppesc11 commented Jul 15, 2026

Copy link
Copy Markdown
Contributor

I added LoadItemsByCamlQueryViaCsomAsync / LoadItemsByCamlQueryViaCsom to IList.

These execute the CAML query via the CSOM List.GetItems(CamlQuery) method instead of the REST GetItems endpoint, so fields projected from joined lists (CAML Joins/ProjectedFields) are now returned as well, typed as IFieldLookupValue.

The loaded items are merged into the list's Items collection like the existing LoadItemsByCamlQuery methods, and the result also returns the PagingInfo from the CSOM ListItemCollectionPosition, which you can set on CamlQueryOptions.PagingInfo to load the next page without constructing the paging string manually.

🔗 Related Issue

Closes #1799

@Adam-it Adam-it changed the title #1799 - CAML queries with Joins/ProjectedFields do not return projected fields - add CSOM-based GetItems support #1799 - CAML queries with Joins/ProjectedFields do not return projected fields - add CSOM-based GetItems support. Closes #1799 Jul 15, 2026
@Adam-it

Adam-it commented Jul 15, 2026

Copy link
Copy Markdown
Member

Thanks @jeppesc11 for opening the PR. We will try to look into it ASAP

@Adam-it Adam-it self-assigned this Aug 3, 2026
@Adam-it Adam-it added the .NET Pull requests that update .net code label Aug 3, 2026
@codecov-commenter

codecov-commenter commented Aug 3, 2026

Copy link
Copy Markdown

⚠️ Please install the 'codecov app svg image' to ensure uploads and comments are reliably processed by Codecov.

Codecov Report

❌ Patch coverage is 84.39898% with 61 lines in your changes missing coverage. Please review.
✅ Project coverage is 81.27%. Comparing base (63545f3) to head (528649e).
⚠️ Report is 3075 commits behind head on dev.

Files with missing lines Patch % Lines
...l/SharePoint/Core/Internal/CsomListItemsHandler.cs 75.22% 36 Missing and 20 partials ⚠️
...M/Requests/ListItems/GetItemsByCamlQueryRequest.cs 95.78% 2 Missing and 2 partials ⚠️
...dk/PnP.Core/Model/SharePoint/Core/Internal/List.cs 94.73% 1 Missing ⚠️
❗ Your organization needs to install the Codecov GitHub app to enable full functionality.
Additional details and impacted files
@@            Coverage Diff             @@
##              dev    #1802      +/-   ##
==========================================
- Coverage   82.42%   81.27%   -1.15%     
==========================================
  Files         416      642     +226     
  Lines       28590    45806   +17216     
  Branches        0     4835    +4835     
==========================================
+ Hits        23565    37229   +13664     
- Misses       5025     7145    +2120     
- Partials        0     1432    +1432     

☔ View full report in Codecov by Harness.
📢 Have feedback on the report? Share it here.

🚀 New features to boost your workflow:
  • ❄️ Test Analytics: Detect flaky tests, report on failures, and find test suite problems.
  • 📦 JS Bundle Analysis: Save yourself from yourself by tracking and limiting bundle sizes in JS merges.

Copilot AI left a comment

Copy link
Copy Markdown
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Pull request overview

This PR adds CSOM-backed CAML query support to IList to correctly return fields projected from joined lists (<Joins> / <ProjectedFields>), addressing the REST GetItems serialization limitation described in #1799. It introduces a CSOM request pipeline for List.GetItems(CamlQuery), materializes returned SP.ListItem JSON into the list’s Items collection, and exposes paging info for seamless page-by-page querying.

Changes:

  • Added IList.LoadItemsByCamlQueryViaCsomAsync/LoadItemsByCamlQueryViaCsom returning a new ICamlQueryCsomResult (items + paging info).
  • Implemented CSOM request/response handling for List.GetItems(CamlQuery) including CamlQuery parameter serialization.
  • Added a CSOM list-item materializer plus unit/integration tests and offline mock recordings for joins + projected fields + paging.

Reviewed changes

Copilot reviewed 30 out of 30 changed files in this pull request and generated 2 comments.

Show a summary per file
File Description
src/sdk/PnP.Core/Services/Core/CSOM/Requests/ListItems/GetItemsByCamlQueryResponse.cs Defines the CSOM GetItems parsed response shape (items + paging info).
src/sdk/PnP.Core/Services/Core/CSOM/Requests/ListItems/GetItemsByCamlQueryRequest.cs Builds CSOM List.GetItems(CamlQuery) request and parses the JSON response.
src/sdk/PnP.Core/Services/Core/CSOM/QueryAction/CamlQueryParameter.cs Serializes SP.CamlQuery (including nested paging position) into CSOM XML.
src/sdk/PnP.Core/Model/SharePoint/Core/Public/IList.cs Exposes the new CSOM-based CAML query methods on the public list API.
src/sdk/PnP.Core/Model/SharePoint/Core/Public/ICamlQueryCsomResult.cs New public result contract for CSOM CAML query execution (items + paging info).
src/sdk/PnP.Core/Model/SharePoint/Core/Internal/List.cs Implements the new IList APIs and wires them into Raw CSOM execution and materialization.
src/sdk/PnP.Core/Model/SharePoint/Core/Internal/CsomListItemsHandler.cs Materializes CSOM SP.ListItem JSON objects into the list’s Items collection with typing.
src/sdk/PnP.Core/Model/SharePoint/Core/Internal/CamlQueryCsomResult.cs Internal implementation of ICamlQueryCsomResult.
src/sdk/PnP.Core.Test/SharePoint/ListTests.cs Adds integration test coverage for joins/projected fields and paging via the new CSOM method.
src/sdk/PnP.Core.Test/Services/Core/CSOM/Requests/GetItemsByCamlQueryRequestTests.cs Adds request XML + response parsing unit tests for the new CSOM request.
src/sdk/PnP.Core.Test/SharePoint/MockData/ListTests/GetItemsByCAMLQueryViaCsomWithJoins-2-00005.response.json Recorded mock response: CSOM list items (page 2).
src/sdk/PnP.Core.Test/SharePoint/MockData/ListTests/GetItemsByCAMLQueryViaCsomWithJoins-2-00004.response.json Recorded mock response: list fields metadata.
src/sdk/PnP.Core.Test/SharePoint/MockData/ListTests/GetItemsByCAMLQueryViaCsomWithJoins-2-00003.response.json Recorded mock response: CSOM list items (page 1 + paging info).
src/sdk/PnP.Core.Test/SharePoint/MockData/ListTests/GetItemsByCAMLQueryViaCsomWithJoins-2-00002.response.json Recorded mock response: list metadata.
src/sdk/PnP.Core.Test/SharePoint/MockData/ListTests/GetItemsByCAMLQueryViaCsomWithJoins-2-00001.response.json Recorded mock response: site metadata.
src/sdk/PnP.Core.Test/SharePoint/MockData/ListTests/GetItemsByCAMLQueryViaCsomWithJoins-2-00000.response.json Recorded mock response: web regional settings metadata.
src/sdk/PnP.Core.Test/SharePoint/MockData/ListTests/GetItemsByCAMLQueryViaCsomWithJoins-0-00013.response.json Recorded mock response: cleanup/no-content response.
src/sdk/PnP.Core.Test/SharePoint/MockData/ListTests/GetItemsByCAMLQueryViaCsomWithJoins-0-00012.response.json Recorded mock response: cleanup/no-content response.
src/sdk/PnP.Core.Test/SharePoint/MockData/ListTests/GetItemsByCAMLQueryViaCsomWithJoins-0-00011.response.json Recorded mock response: validate-update-item response (item 3).
src/sdk/PnP.Core.Test/SharePoint/MockData/ListTests/GetItemsByCAMLQueryViaCsomWithJoins-0-00010.response.json Recorded mock response: validate-update-item response (item 2).
src/sdk/PnP.Core.Test/SharePoint/MockData/ListTests/GetItemsByCAMLQueryViaCsomWithJoins-0-00009.response.json Recorded mock response: list fields metadata.
src/sdk/PnP.Core.Test/SharePoint/MockData/ListTests/GetItemsByCAMLQueryViaCsomWithJoins-0-00008.response.json Recorded mock response: validate-update-item response (item 1).
src/sdk/PnP.Core.Test/SharePoint/MockData/ListTests/GetItemsByCAMLQueryViaCsomWithJoins-0-00007.response.json Recorded mock response: field metadata (JoinLookup).
src/sdk/PnP.Core.Test/SharePoint/MockData/ListTests/GetItemsByCAMLQueryViaCsomWithJoins-0-00006.response.json Recorded mock response: list fields metadata.
src/sdk/PnP.Core.Test/SharePoint/MockData/ListTests/GetItemsByCAMLQueryViaCsomWithJoins-0-00005.response.json Recorded mock response: validate-update-item response (lookup item).
src/sdk/PnP.Core.Test/SharePoint/MockData/ListTests/GetItemsByCAMLQueryViaCsomWithJoins-0-00004.response.json Recorded mock response: field metadata (ProjectedSourceText).
src/sdk/PnP.Core.Test/SharePoint/MockData/ListTests/GetItemsByCAMLQueryViaCsomWithJoins-0-00003.response.json Recorded mock response: list creation metadata.
src/sdk/PnP.Core.Test/SharePoint/MockData/ListTests/GetItemsByCAMLQueryViaCsomWithJoins-0-00002.response.json Recorded mock response: list creation metadata (lookup list).
src/sdk/PnP.Core.Test/SharePoint/MockData/ListTests/GetItemsByCAMLQueryViaCsomWithJoins-0-00001.response.json Recorded mock response: site metadata.
src/sdk/PnP.Core.Test/SharePoint/MockData/ListTests/GetItemsByCAMLQueryViaCsomWithJoins-0-00000.response.json Recorded mock response: web regional settings metadata.

💡 Add Copilot custom instructions for smarter, more guided reviews. Learn how to get started.

@Adam-it Adam-it left a comment

Copy link
Copy Markdown
Member

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

@jeppesc11 amaizing work 👏.
Checked locally ✅
I only left a few concerns about some edge cases I noticed that I think it's worth recheking before we merge.
I would also suggest we extend the docs https://github.com/pnp/pnpcore/blob/dev/docs/using-the-sdk/listitems-intro.md providing new examples how to use the added methods in this PR

Comment thread src/sdk/PnP.Core/Model/SharePoint/Core/Internal/CsomListItemsHandler.cs Outdated
Comment thread src/sdk/PnP.Core/Model/SharePoint/Core/Internal/CsomListItemsHandler.cs Outdated
Comment thread src/sdk/PnP.Core/Model/SharePoint/Core/Internal/List.cs Outdated
@Adam-it
Adam-it marked this pull request as draft August 3, 2026 23:55
@jeppesc11
jeppesc11 marked this pull request as ready for review August 7, 2026 06:02
@jeppesc11
jeppesc11 marked this pull request as draft August 7, 2026 06:03
jeppesc11 and others added 2 commits August 7, 2026 08:08
Co-authored-by: Copilot Autofix powered by AI <175728472+Copilot@users.noreply.github.com>
@jeppesc11
jeppesc11 marked this pull request as ready for review August 7, 2026 11:12
@jeppesc11

Copy link
Copy Markdown
Contributor Author

Thanks for the thorough review @Adam-it 🙏 I've pushed a commit addressing the feedback.

@Adam-it Adam-it left a comment

Copy link
Copy Markdown
Member

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

LGTM 🔥

@Adam-it
Adam-it merged commit 8a27fca into pnp:dev Aug 9, 2026
3 checks passed
Adam-it added a commit that referenced this pull request Aug 9, 2026
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Labels

.NET Pull requests that update .net code

Projects

None yet

Development

Successfully merging this pull request may close these issues.

Feature: CAML queries with Joins/ProjectedFields do not return projected fields - add CSOM-based GetItems support

4 participants