Skip to content

fix(query): prefer OrderExpression.Alias over EntityName in CollectOrders#44

Merged
LarsBauer merged 3 commits into
betafrom
fix/link-entity-order-3
Jun 19, 2026
Merged

fix(query): prefer OrderExpression.Alias over EntityName in CollectOrders#44
LarsBauer merged 3 commits into
betafrom
fix/link-entity-order-3

Conversation

@LarsBauer

Copy link
Copy Markdown
Contributor

Root-level cross-entity ordering was broken when using the 3-arg OrderExpression constructor, which sets only Alias (EntityName stays null). The beta.11 partial fix read EntityName instead, so the sort key was never resolved and TopCount=1 returned by insertion order.

CollectOrders now mirrors the precedence rule already used in CollectLinkOrders: Alias is checked first, EntityName is the fallback, null means root-entity attribute.

Tests added (QueryBugsTests):

  • 3-arg constructor descending → TopCount=1 returns highest linked value
  • 3-arg constructor ascending → returns lowest linked value
  • 4-arg constructor (both Alias + EntityName set) → Alias wins
  • EntityName-only fallback (no Alias) → EntityName used as key prefix

…ders

Root-level cross-entity ordering was broken when using the 3-arg
OrderExpression constructor, which sets only Alias (EntityName stays
null). The beta.11 partial fix read EntityName instead, so the sort
key was never resolved and TopCount=1 returned by insertion order.

CollectOrders now mirrors the precedence rule already used in
CollectLinkOrders: Alias is checked first, EntityName is the fallback,
null means root-entity attribute.

Tests added (QueryBugsTests):
- 3-arg constructor descending → TopCount=1 returns highest linked value
- 3-arg constructor ascending → returns lowest linked value
- 4-arg constructor (both Alias + EntityName set) → Alias wins
- EntityName-only fallback (no Alias) → EntityName used as key prefix
@LarsBauer
LarsBauer requested a review from PepperPix June 19, 2026 07:15
@github-actions

github-actions Bot commented Jun 19, 2026

Copy link
Copy Markdown

Qodana Community for .NET

It seems all right 👌

No new problems were found according to the checks applied

View the detailed Qodana report

To be able to view the detailed Qodana report, you can either:

To get *.log files or any other Qodana artifacts, run the action with upload-result option set to true,
so that the action will upload the files as the job artifacts:

      - name: 'Qodana Scan'
        uses: JetBrains/qodana-action@v2026.1.0
        with:
          upload-result: true
Contact Qodana team

Contact us at qodana-support@jetbrains.com

@LarsBauer
LarsBauer merged commit 890d912 into beta Jun 19, 2026
8 checks passed
@LarsBauer
LarsBauer deleted the fix/link-entity-order-3 branch June 19, 2026 08:15
PepperPix pushed a commit that referenced this pull request Jun 19, 2026
# [1.1.0-beta.12](v1.1.0-beta.11...v1.1.0-beta.12) (2026-06-19)

### Bug Fixes

* **query:** prefer OrderExpression.Alias over EntityName in CollectOrders ([#44](#44)) ([890d912](890d912))
@github-actions

Copy link
Copy Markdown

🎉 This PR is included in version 1.1.0-beta.12 🎉

The release is available on:

Your semantic-release bot 📦🚀

PepperPix pushed a commit that referenced this pull request Jul 1, 2026
# [1.1.0](v1.0.0...v1.1.0) (2026-07-01)

### Bug Fixes

* **bulk-delete:** copy RecurrencePattern and StartDateTime to asyncoperation ([3cffda7](3cffda7))
* **bulk-delete:** omit recurrencepattern and recurrencestarttime when not set ([0c0a2e8](0c0a2e8))
* **bulk-delete:** populate name, ownerid, and operationtype on asyncoperation entity ([2ac6f28](2ac6f28))
* deep-clone OptionSetValue instances inside OptionSetValueCollection ([dd72956](dd72956))
* enforce single-child and entity type validation for N:1 deep insert ([7ae25aa](7ae25aa))
* ensure CloneEntity returns base Entity runtime type ([f393387](f393387))
* fall back to EntityLogicalNameAttribute in CreateQuery<T> when type is not in resolver cache ([5ba7140](5ba7140))
* merge attributes on Update instead of replacing the entire entity ([753ecd6](753ecd6))
* **query:** clone outer entity per row in LeftOuter join ([501db49](501db49))
* **query:** fix 4 critical query engine bugs ([ef0e7e4](ef0e7e4))
* **query:** guard against null Attributes array in PatchDateFormat ([3021776](3021776))
* **query:** handle null otherEntity in JoinAttributes for left outer joins ([a7c67cb](a7c67cb))
* **query:** honor LinkEntity.Orders in RetrieveMultiple ordering ([#42](#42)) ([4b363b1](4b363b1))
* **query:** honor root-level OrderExpression.EntityName for linked-entity sorting ([#43](#43)) ([102de5d](102de5d))
* **query:** match primary id attribute against Entity.Id in RetrieveMultiple ([5853fb6](5853fb6))
* **query:** materialize DateTime attributes before modifying collection in PatchDateFormat ([dd4d2e3](dd4d2e3))
* **query:** pass Guid directly for EqualUserId/EqualBusinessId conditions ([e7b8c77](e7b8c77))
* **query:** prefer OrderExpression.Alias over EntityName in CollectOrders ([#44](#44)) ([890d912](890d912))
* **query:** treat fetchxml bool condition values without metadata as bool ([8be757e](8be757e))
* **query:** use fiscalYear from condition as year for InFiscalYear date range ([e4677e6](e4677e6))
* **query:** use TimeOnly.MaxValue for end-of-day upper bound in date range operators ([49b1679](49b1679))
* **query:** validate actual values in aggregate FetchXml guards ([fe9cfcf](fe9cfcf))
* remove 14 redundant using directives ([1771050](1771050))
* remove 5 unused local variables ([a94494e](a94494e))
* remove redundant System.Reflection qualifier ([5367eb2](5367eb2))
* replace Activator.CreateInstance with plain Entity in ProjectAttributes ([a87bb5b](a87bb5b))
* replace generic exceptions with Dataverse-style FaultException ([fb21ac0](fb21ac0))
* replace obsolete HasCount() with Count().IsEqualTo() ([d8c5857](d8c5857))
* resolve ambiguous XML doc comment reference ([2a6be1b](2a6be1b))
* **retrieve:** translate QueryByAttribute Attributes/Values and Orders in RetrieveFake ([1bffa18](1bffa18))
* skip ownerid default when proxy type has no ownerid attribute ([714dd89](714dd89))
* support reverse-direction (ManyToOne) nested deep insert ([00df6e8](00df6e8))
* use Count property instead of Count() method ([49c69cd](49c69cd))
* validate maxRetrieveCount argument in WithMaxRetrieveCount ([3c7797d](3c7797d))
* validate relationship metadata matches parent entity in DeepInsertProcessor ([2a6952a](2a6952a))

### Features

* add FetchXmlToQueryExpression organization request fake ([5885467](5885467))
* add QueryExpressionToFetchXml organization request fake ([c0366cb](c0366cb))
* add RelatedEntitiesQuery support to RetrieveFake ([868a555](868a555))
* add RetrieveAllEntities organization request fake ([83db189](83db189))
* add RetrieveAttributeFake implementation ([e64ac18](e64ac18))
* **query:** implement CompareColumns and MatchFirstRowUsingCrossApply ([b4f9bd1](b4f9bd1))
* **query:** support EXISTS-style semi-joins via JoinOperator.Any/NotAny/Exists ([63df498](63df498))
* **query:** support FilterExpression.AnyAllFilterLinkEntity and JoinOperator.All/NotAll ([87704f4](87704f4))
* route Create/Update/Delete/Retrieve/Associate/Disassociate through Execute pipeline ([374604b](374604b))
* set audit fields and RowVersion on Create and Update ([f1c7f92](f1c7f92))
* support deep insert (RelatedEntities) in CreateFake and UpsertFake ([103f0de](103f0de))
* use Options class for explicit configuration ([8482732](8482732))

### Performance Improvements

* cache EntityLogicalNameAttribute lookup in CreateQuery<T> ([863ba8d](863ba8d))
* cache MethodInfo lookups in ConditionParser as static readonly fields ([0f89d70](0f89d70))
* compile proxy converter delegates via expression trees ([1c38463](1c38463))
* use pattern matching in XrmOrderByAttributeComparer ([f035a4a](f035a4a))
@github-actions

github-actions Bot commented Jul 1, 2026

Copy link
Copy Markdown

🎉 This PR is included in version 1.1.0 🎉

The release is available on:

Your semantic-release bot 📦🚀

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Projects

None yet

Development

Successfully merging this pull request may close these issues.

1 participant