Skip to main content

Notifications

Announcements

No record found.

Microsoft Dynamics CRM (Archived)

Auto Numbering Plugin

(0) ShareShare
ReportReport
Posted on by 2,397

Hi, I am working on a simple auto numbering plugin for case number on case entity. The format should be "yyyymmxxxx" and xxxx is the incremental number. I am wondering how to handle the concurrency, for example, when multiple users generate case number at the same time. I attached the sample code as below:

            IPluginExecutionContext context = localContext.PluginExecutionContext;
            IOrganizationService service = localContext.OrganizationService;
            int maxNumber;

            if (context.InputParameters.Contains("Target") &&
              context.InputParameters["Target"] is Entity)
            {
                Entity entity = (Entity)context.InputParameters["Target"];
                if (entity.LogicalName == "incident")
                {
                    if (entity.Attributes.Contains("caseid") == false)
                    {
                        string fetchxml = @"<fetch version='1.0' output-format='xml-platform' distinct='false' mapping='logical'>
                                    <entity name='incident'>
                                        <attribute name='caseid'/>
                                    </entity>
                                </fetch>";
                        EntityCollection ec = service.RetrieveMultiple(new FetchExpression(fetchxml));
                        List<int> list = new List<int>();
                        foreach (var c in ec.Entities)
                        {
                            if (c.Attributes.ContainsKey("caseid"))
                            {
                                list.Add(int.Parse(c.Attributes["caseid"].ToString()));
                            }
                        }
                        maxNumber = list.Max();
                                   
                        entity.Attributes.Add("caseid", Autonumbering(maxNumber));
                    }
                }
            }

        private string Autonumbering(int caseNumber)
        {
            string caseid = string.Empty;
            string year = DateTime.Now.Year.ToString();
            string month = DateTime.Now.ToString("MM");
            if (year == caseNumber.ToString().Substring(0, 4))
            {
                if (month == caseNumber.ToString().Substring(4, 2))
                {
                    caseid = year + month + (caseNumber + 1).ToString().Substring(6, 4);
                }
                else
                {
                    caseid = year + month + "0001";
                }
            }
            else
            {
                caseid = year + month + "0001";
            }
            return caseid;
        }


*This post is locked for comments

  • Suggested answer
    Community Member Profile Picture
    Community Member Microsoft Employee on at
  • Verified answer
    ashlega Profile Picture
    ashlega 34,475 on at
    RE: Auto Numbering Plugin

    As David explained, you need to implement locking. There is a "classic" article on this subject:

    www.greenbeacon.com/.../how-to-implement-robust-auto-numbering-using-transactions-in-microsoft-dynamics-crm

  • sdnd2000 Profile Picture
    sdnd2000 2,397 on at
    RE: Auto Numbering Plugin

    So, currently, I just have one customized field in case entity, and the problem is that when creating records, duplicates are also created, how can I avoid that?

  • Verified answer
    David Jennaway Profile Picture
    David Jennaway 14,063 on at
    RE: Auto Numbering Plugin

    There are several options re concurrency, with varying levels of robustness. You need to be able to lock some resource to ensure no duplicates. The main options are:

    • If you have CRM OnPremise, you can use a resource that is external to CRM, which is the most robust option. In this scenario I'd use a SQL table to manage the number generation, either with explicit locking, or using an identity column
    • If you have CRM Online, or don't want an external resource, then the options are:
      • Locking code blocks. This is not reliable, as you have no control over the execution context of plugin code, and (especially in CRM Online, but also multi-server deployments) plugins may run concurrently on multiple servers
      • Using a separate lock entity to provide numbers. This can be locked by using an initial Update on the lock entity (to lock it), then generate the next number, then update the lock entity again based on the new value. This works for most scenarios, but can generate duplicates if multiple records are created simultaneously via an asynchronous workflow. The reason for this is that asynchronous workflow instances may share the same transaction.  

Under review

Thank you for your reply! To ensure a great experience for everyone, your content is awaiting approval by our Community Managers. Please check back later.

Helpful resources

Quick Links

December Spotlight Star - Muhammad Affan

Congratulations to a top community star!

Top 10 leaders for November!

Congratulations to our November super stars!

Tips for Writing Effective Verified Answers

Best practices for providing successful forum answers ✍️

Leaderboard

#1
André Arnaud de Calavon Profile Picture

André Arnaud de Cal... 291,391 Super User 2024 Season 2

#2
Martin Dráb Profile Picture

Martin Dráb 230,445 Most Valuable Professional

#3
nmaenpaa Profile Picture

nmaenpaa 101,156

Leaderboard

Featured topics

Product updates

Dynamics 365 release plans