简体   繁体   中英

MS Dynamics365 - generate custom serial number, ensure uniqueness

I am developing a Dynamics365 CRM based solution, and for a custom entity we've defined, we need to create custom serial numbers.

For various business reasons, neither a GUID nor a sequential numbering scheme will do - business insists on a format of

99-9999-9999

where each group of numbers is basically a random group of numbers.

Creating those in a plugin is easy - but how do I ensure uniqueness ?? I'm a C#/SQL Server developer at heart, and in SQL Server / T-SQL, I'd just create an unique index on my "Entity" table on this column. Checking if a newly created number exists would be easy-peasy - just do an

IF EXISTS (SELECT * FROM dbo.MyEntity WHERE SerialNum = @SerialNumGenerated)

check, and since that single column is indexed and NOT NULL , it would be quite fast, too.

But how do I do the same (at least as "same" as possible) in Dynamics365? How can I programmatically check (inside my C# plugin) if a newly created "serial number" has not yet been used - and do so it's quick enough not to slow down the save process too much? Can I somehow also "index" that property on my custom entity and do something similar to the IF EXISTS() check in T-SQL ?

Thanks for any hints or pointers!

Assuming you are unable to design a generation formula that is astronomically unlikely to generate duplicates (eg a GUID). You will need to follow this general logic.

  1. Run formula to create a unique id.
  2. Search CRM via RetrieveMultiple to check for any records with that number already.
  3. If number already exists; go back to 1.
  4. Else; update record with new id.

You then have to decide where to execute your code. Two options spring to mind.

  1. In the 'box', eg a plugin or JavaScript. In this case you would have the issue that its possible to have multiple executions of your formula concurrently with no knowledge of each other. Depending on how likely your formula is to generate duplicates and the rate that records are created this may be acceptable.

  2. Go out of the 'box', eg a console application running on a schedule that finds records without numbers. It then numbers each record one by one. A single threaded approached has the benefit of ensuring uniqueness, but is going to be slower from a user perspective.

If it was me and I had to implement this requirement, I would go for option 2.

You want to do this numbering within a pre-operation plugin. This is the only way to completely guarentee uniqueness, it is quite performant, and the number will immediately exist upon creation of the record.

1) Generate the characters
You can use whatever method you want, as a database developer I usually just default to what I am familiar with, a substring of Guid.NewGuid().ToString();

2) Check uniqueness

    QueryExpression query = new QueryExpression("[prefix_yourentityname]")
    query.Criteria.AddCondition("prefix_yourfieldname", ConditionOperator.Equal, [IDNumber]);
    query.TopCount = 1;
    bool isUnique = Service.RetrieveMultiple(query).Entities.Count = 0;

3) Set the ID number on the target so that it is saved with the transaction

Performance:
This check obviously results in a small read operation against the database but you don't have a better option. If you are using on-premise CRM you can add an index against this table including the ID field. Indexing the CRM database is supported by Microsoft.

If you are using CRM online, the only thing you can do is add your ID field to the Quick Find View "View Columns" and "Search Columns" for this entity. The CRM application generates an index on each table based on the configuration within the Quick Find view, so adding your ID column to this view will result in that field being added to the index.

The technical post webpages of this site follow the CC BY-SA 4.0 protocol. If you need to reprint, please indicate the site URL or the original address.Any question please contact:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM