Javascript 如何在CRM Online 2013中拥有唯一的ID号

Javascript 如何在CRM Online 2013中拥有唯一的ID号,javascript,dynamics-crm-2011,dynamics-crm,crm,dynamics-crm-online,Javascript,Dynamics Crm 2011,Dynamics Crm,Crm,Dynamics Crm Online,我正在使用CRM Online 2013,在我的自定义实体中有一个名为ID的唯一字段。此ID是手动输入的,需要唯一。是否有办法检查该ID是否已在其他记录中输入?例如,如果以前有ID为111、222、333的记录,并且如果用户试图保存ID为111的新记录,则应发出警报 然而,我不赞成用户输入唯一号码。出于性能原因,它应该是自动生成的。此外,如果用户必须多次输入数字才能找到唯一的数字,这可能会让用户感到沮丧。除非您有任何定义的模式,否则用户不可能猜出唯一的数字 但你仍然可以通过在预验证或预操作中编写

我正在使用CRM Online 2013,在我的自定义实体中有一个名为
ID
的唯一字段。此ID是手动输入的,需要唯一。是否有办法检查该ID是否已在其他记录中输入?例如,如果以前有ID为111、222、333的记录,并且如果用户试图保存ID为111的新记录,则应发出警报

然而,我不赞成用户输入唯一号码。出于性能原因,它应该是自动生成的。此外,如果用户必须多次输入数字才能找到唯一的数字,这可能会让用户感到沮丧。除非您有任何定义的模式,否则用户不可能猜出唯一的数字

但你仍然可以通过在预验证或预操作中编写插件来实现你想要的。在插件中检查Id等于给定Id的现有记录。如果以前使用过,则抛出新的
InvalidPluginExecutionException
,并显示错误消息


由于若数据库中有数百万条记录,那个么这将是一个繁重的查询,所以我建议您在该列上设置SQL索引,以缩短处理时间。或使用自动生成的唯一值填充字段

我会使用双管齐下的方法。在Id字段的onChange事件期间,通过javascript执行Odata,并警告用户它是否已经在使用中。这可能是所需的全部,但它使人a和人B在同一时间输入同一id之间存在种族条件的可能性成为可能。在这种情况下,您需要一个插件来确认它是唯一的


Odata调用让用户更容易获得即时反馈,插件只是帮助缩小竞争条件差距。

这里是一个粗略的未经测试的基本代码示例,您需要使用它来检查值的唯一性。如果您希望创建大量记录,我建议在unique字段和primary key字段上添加索引,以提高性能

/// <summary>
    /// Determines if the uniqueField contains a unique value.
    /// </summary>
    /// <param name="entityName">Logical Name of the entity being checked</param>
    /// <param name="uniqueField">Field on the entity to check for uniqueness</param>
    /// <param name="recordIdField">Field on the entity that is hte Primary Key (not attribute) of the Entity - should be logical name of the entity followed by 'id' (i.e., accountid)</param>
    /// <param name="valueToCheck">Value to ensure is unique to this record</param>
    /// <param name="currentRecordId">Id (Primary Key) of the current record</param>
    /// <param name="service">An instance of IOrganizationService with Organization-wide permission to read the entity</param>
    /// <returns></returns>
    public bool isUniqueRecord(string entityName, string uniqueField, string recordIdField, string valueToCheck, Guid currentRecordId, IOrganizationService service)
    {
        var query = new QueryExpression(entityName)
        {
            ColumnSet = new ColumnSet(true)
        };

        var criteria = new FilterExpression(LogicalOperator.And);
        criteria.AddCondition(new ConditionExpression(uniqueField, ConditionOperator.Equal, valueToCheck));
        criteria.AddCondition(new ConditionExpression(recordIdField, ConditionOperator.NotEqual, currentRecordId));

        query.Criteria = criteria;

        var result = service.RetrieveMultiple(query);

        if (result.Entities.Any()) return false;
        else return true;            

    }
//
///确定uniqueField是否包含唯一值。
/// 
///正在检查的实体的逻辑名称
///要检查唯一性的实体上的字段
///实体上作为实体主键(非属性)的字段-应为实体的逻辑名称,后跟“id”(即accountid)
///要确保此记录唯一的值
///当前记录的Id(主键)
///具有读取实体的组织范围权限的IOOrganizationService实例
/// 
public bool isUniqueRecord(字符串entityName、字符串uniqueField、字符串recordIdField、字符串值ToCheck、Guid currentRecordId、IOrganizationService)
{
var query=new QueryExpression(entityName)
{
ColumnSet=新列集(true)
};
var标准=新的FilterExpression(LogicalOperator.And);
AddCondition(新的ConditionExpression(uniqueField,ConditionOperator.Equal,valueToCheck));
criteria.AddCondition(新的ConditionExpression(recordIdField,ConditionOperator.NotEqual,currentRecordId));
query.Criteria=条件;
var result=service.RetrieveMultiple(查询);
if(result.Entities.Any())返回false;
否则返回true;
}

为什么要用户输入唯一的号码?这对用户来说是令人沮丧的。看看salyh的答案,这里有一个很好的解释了使用CRM插件进行自动编号的方法。手动输入ID是一项要求,否则我知道自动编号插件。好的,在这种情况下,您将仅限于蝎子答案,或者,您也可以使用javascript执行客户端检查,以使用警报消息执行相同类型的查询。如果有可能在一起创建多个记录,那么在任何情况下都无法使其100%可靠。CRM 2011中的重复检测功能可能是可行的,但我相信它在2013年已经发生了足够的变化,不适合您。OP提到CRM Online,因此将无法应用自定义索引。另外,您的解决方案没有考虑到将发生的并发问题(编辑:最初没有看到您的最后一句话)。CRM中有一些自动编号的ok方法,它们利用插件和数据库事务确保uniquenessA unique ID字段与我将添加到“快速查找”视图中的“查找”列中的字段完全相同,以确保用户可以搜索此字段。将字段添加到快速查找列将在2013年自动为该列添加非聚集索引(包括在线)。嗨@Daryl,我知道通过JavaScript的Odata可以提供即时反馈,用户无需按下保存按钮即可获得错误消息。但是我认为让Odata调用和插件在一个进程上同时检查同一件事有点过分了。我知道它可以消除用户的反复试验(不需要按相同的按钮来尝试),但我们仍然在运行一个额外的查询。@Scorpion同意。这一切都是关于用户体验,如果它值得的价格。