XrmMockup icon indicating copy to clipboard operation
XrmMockup copied to clipboard

Add support for NotAny join operator in Query Expression

Open Copilot opened this issue 5 months ago • 1 comments

This PR implements support for the NotAny join operator in XrmMockup Query Expression, addressing the limitation where only LeftOuter join was previously supported.

What was implemented

The NotAny join operator provides anti-join functionality, returning records from the primary entity that do NOT have matching records in the linked entity.

Key changes:

  1. FetchXML parsing support - Added "notany" link-type parsing in XmlHandling.cs:

    <link-entity name='lead' from='parentcontactid' to='contactid' link-type='notany' />
    
  2. Query Expression support - Added JoinOperator.NotAny handling in RetrieveMultipleRequestHandler.cs:

    var linkEntity = new LinkEntity() {
        JoinOperator = JoinOperator.NotAny,
        // ... other properties
    };
    
  3. Anti-join logic - Implemented proper NotAny behavior:

    • Returns parent entity when no matching linked entities are found
    • Returns nothing when matching linked entities are found

Example usage

// Find contacts that do NOT have any associated leads
var query = new QueryExpression("contact") {
    ColumnSet = new ColumnSet("contactid", "lastname")
};

query.LinkEntities.Add(new LinkEntity() {
    LinkToEntityName = "lead",
    LinkToAttributeName = "parentcontactid", 
    LinkFromEntityName = "contact",
    LinkFromAttributeName = "contactid",
    JoinOperator = JoinOperator.NotAny
});

var contactsWithoutLeads = orgService.RetrieveMultiple(query);

Testing

Added comprehensive test coverage including both QueryExpression and FetchXML scenarios. The implementation follows the same patterns as existing join operators and maintains full backward compatibility.

Fixes #280.


✨ Let Copilot coding agent set things up for you — coding agent works faster and does higher quality work when set up for your repo.

Copilot avatar Sep 10 '25 08:09 Copilot

@KristianKlodeD 👋 This repository doesn't have Copilot instructions. With Copilot instructions, I can understand the repository better, work faster and produce higher quality PRs.

I can generate a .github/copilot-instructions.md file for you automatically. Click here to open a pre-filled issue and assign it to me. I'll write the instructions, and then tag you for review.

Copilot avatar Sep 10 '25 08:09 Copilot