在Dynamics 365 CRM中的自定义表上创建唯一索引

时间:2017-12-07 17:46:35

标签: dynamics-crm unique-index xrm

使用Dynamics365 Sdk将数据写入自定义实体 new_licenseRecordsSet 时,在Dynamis CRM数据库中,我遇到了一些并发问题,有时会在目标表中创建完全重复的记录。检查现有记录的代码(并且仅在现有记录为空时创建新许可证)如下所示似乎并不总是有效(98%的时间它确实有效)。

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;
            }

    }

不确定为什么这个检查在2%的时间内失败并且仍然在new_licenseRecordsSet中创建了确切的重复记录,我决定在目标表上创建唯一索引,其中包括以下三列:LicenseId,AccountId和InstanceId。但是我该怎么办呢?我们的DBA禁止在SQL Server中进行任何模式的替换,我无法从Dynamics CRM UI中找到任何其他方法来让我在自定义实体上添加唯一约束。

我的问题:

  1. 检查现有记录时可能导致代码失败的原因是什么?我猜测可能有两个并发线程同时检查同一条记录并且都返回null并且两者都导致创建新记录。如果是这种情况,我如何强制锁定以避免并发检查?
  2. 关于在自定义new_LicenseRecords表上创建唯一索引,最好的方法是什么?有没有Sdk方法呢?我搜索了一下,但此时没有找到。
  3. 提前致谢。

1 个答案:

答案 0 :(得分:0)

给你一些想法:

最后我检查过,只有两个支持与SQL的直接交互:

  1. 访问已过滤的查询以查询查询,SSRS报告等
  2. 创建自定义索引
  3. 不支持对SQL数据库的任何其他修改,包括添加约束。

    您可能想要考虑创建alternate key

    ,而不是使用SQL做任何事情

    您可能还想查看开箱即用的duplicate detection功能。

    另外,你是如何启动代码的?一个插件?