How to Limit the Maximum Number of Records in a D365 View (Top N) Using a Plugin

 Requirement

We need to limit how many records a Dynamics 365 (D365) view returns. Since there’s no out-of-box (OOB) way to do this, we introduced a custom column dsl_topn. This column holds the “Top N” value we want. A plugin then intercepts the FetchXML query and injects the <fetch top="N"/> attribute, removing any conflicting paging attributes in the process.

Plugin Highlights

  • Trigger: RetrieveMultiple (PreOperation) for the dsl_trip entity.
  • FetchXML Intercept: If a condition with attribute="dsl_topn" exists, read it, remove paging attributes (page, count, paging-cookie, returntotalrecordcount), and set top to the requested value.
  • Condition Removal: Removes the dsl_topn condition so it doesn’t appear anywhere else.

C# Plugin Code

using Microsoft.Xrm.Sdk;
using Microsoft.Xrm.Sdk.Query;
using System;
using System.Collections.Generic;
using System.Linq;
using System.Xml.Linq;

namespace Trip.Plugins
{
    public class SetViewTopN : IPlugin
    {
        public void Execute(IServiceProvider serviceProvider)
        {
            ITracingService tracingService = (ITracingService)serviceProvider.GetService(typeof(ITracingService));
            IPluginExecutionContext context = (IPluginExecutionContext)serviceProvider.GetService(typeof(IPluginExecutionContext));

            // PreOperation stage on RetrieveMultiple message for dsl_trip
            if (context.MessageName.Equals("RetrieveMultiple", StringComparison.OrdinalIgnoreCase)
                && context.PrimaryEntityName.Equals("dsl_trip", StringComparison.OrdinalIgnoreCase)
                && context.Stage == 20)
            {
                if (context.InputParameters.TryGetValue("Query", out object queryObj))
                {
                    // If the query is FetchExpression
                    if (queryObj is FetchExpression fx)
                    {
                        var doc = XDocument.Parse(fx.Query);

                        // Find condition with dsl_topn
                        var topNConditions = doc
                            .Descendants("condition")
                            .Where(x => (string)x.Attribute("attribute") == "dsl_topn")
                            .ToList();

                        foreach (var cond in topNConditions)
                        {
                            if (int.TryParse((string)cond.Attribute("value"), out int topN) && topN > 0)
                            {
                                // Remove paging attributes to avoid conflict with top
                                doc.Root?.Attribute("page")?.Remove();
                                doc.Root?.Attribute("paging-cookie")?.Remove();
                                doc.Root?.Attribute("count")?.Remove();
                                doc.Root?.Attribute("returntotalrecordcount")?.Remove();

                                // Apply top
                                doc.Root?.SetAttributeValue("top", topN);
                            }

                            // Remove the original condition
                            cond.Remove();
                        }

                        // Update the FetchXML
                        fx.Query = doc.ToString();
                    }
                }
            }
        }
    }
}


Use this approach to quickly limit D365 view records to a custom Top N count without modifying core functionality.




No comments:

Post a Comment