简体   繁体   中英

Create unique index on custom tables in Dynamics 365 CRM

While using Dynamics365 Sdk to write data to a custom entity, new_licenseRecordsSet , in Dynamis CRM database, I encountered some concurrency issue where an exact duplicate record sometimes would be created in the targeted table. The code to check existing record (and created new License only when the existing record is null) as shown below seemed not always working (in 98% of time it did work).

private LicenseRecDto GetExistingLicRecord(int accountId, short instanceId, int licenseId, IOrganizationService service)
    {
        var context = new DynamicsCrmProxyContext(service);
        var dynamicsExpectedInstanceId = (Int32)instanceId; // Dynamic sdk will throw exception of not casting a short; weird but true

        //In some rare cases we found there were exact duplicates of same License record in Dynamics CRM. Using FirstOrDefault instead of SingleOrDefault will avoid throwing unnecessary exception and 
        //make the same record got created again and again in Dynamics.
        var license = context.new_licenseRecordsSet
            .Where(
                l => l.new_LicenseID == licenseId
                     && l.new_InstanceID == dynamicsExpectedInstanceId
                     && l.new_AccountId == accountId)
            .OrderByDescending(d => d.VersionNumber)
            .FirstOrDefault();

        return license?.MapToDynamicsObject<LicenseRecDto>();
    }

private void CreateUpdateLicense(LicenseRecDto license, IOrganizationService service)
    {
        var dynamicsLicense = GetExistingLicRecord(license.AccountId, license.InstanceId, license.LicenseId, service);

            if (dynamicsLicense != null)
            {
                license.DynamicsLicenseGuid = dynamicsLicense.DynamicsLicenseGuid;
                UpdateLicense(license, service);
            }
            else
            {
                var result = CreateLicense(license, service);
                if (result != Guid.Empty)
                    license.DynamicsLicenseGuid = result;
            }

    }

Not sure why this check failed in 2% of time and exact duplicated record still got created in the new_licenseRecordsSet, I decided to create unique index on the targeted table with these three columns included: LicenseId, AccountId, and InstanceId. But how will I proceed? Our DBA disallowed any alternation in schema from SQL Server and I couldn't find any other way from Dynamics CRM UI to let me add unique constraint on the custom entity.

My questions:

  1. What could have caused the codes to fail while checking existing record? My speculation is there might be two concurrent threads checking on same record at the same time and both returned null and both led to creating new record. If that's the case, how can I impose locking to avoid concurrent check?
  2. About creating unique index on the custom new_LicenseRecords table, what's the best approach? Is there Sdk method to do it? I searched and found none at this point.

Thanks in advance.

A few thoughts for you:

Last I checked, there are only two supported direct interactions with SQL:

  1. Access the filtered views for queries, SSRS reports, etc.
  2. Create custom indexes

Any other modifications to the SQL database are unsupported, including adding constraints.

Rather than doing anything with SQL you might want to think about creating an alternate key .

You might also want to look into the out-of-box duplicate detection functionality.

Also, how are you launching the code? a plugin?

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