Dynamics CRM 2013:检查联系人账户连接时SDK查询400错误咨询
解决Dynamics CRM 2013 Connection实体OData查询400错误及重复关联验证问题
看起来你在实现员工-公司重复关联验证时踩了两个关键的OData查询误区,我来帮你理清问题并修正代码:
问题根源分析
你遇到的400错误主要来自两个错误的逻辑:
- 混淆了
Record2RoleId和Record2Id:Record2RoleId是用来标记连接角色的实体引用(比如“员工”“合作伙伴联系人”这类角色类型),而你要筛选的是关联的Contact实体,对应的字段应该是Record2Id。用Record2RoleId来过滤联系人名称完全不符合需求。 - EntityReference类型字段的OData查询语法错误:
在CRM的OData服务中,EntityReference类型的字段(比如各种xxxId字段)不能直接访问Name或FullName属性。如果要筛选关联实体的属性,要么用$expand展开关联实体后访问,要么更高效地用实体Id来过滤(优先推荐用Id,避免重名问题)。
修正后的验证代码
下面是符合你需求的完整代码:
function validateContact() { // 获取当前Connection的关联账户(Record1Id)和联系人(Record2Id)字段 var record2IdAttr = Xrm.Page.data.entity.attributes.get("record2id"); var record1IdAttr = Xrm.Page.data.entity.attributes.get("record1id"); // 检查两个关联字段是否都已填写 if (!record2IdAttr.getValue() || !record1IdAttr.getValue()) { return; } // 获取账户和联系人的Guid(注意去掉{}括号,CRM OData需要纯Guid字符串) var contactId = record2IdAttr.getValue()[0].id.replace(/[{}]/g, ""); var accountId = record1IdAttr.getValue()[0].id.replace(/[{}]/g, ""); // 构造正确的OData查询:查找同一账户、同一联系人且EffectiveEnd为空的Connection记录 var entityType = "Connection"; var queryOptions = "$select=ConnectionId&$filter=Record1Id/Id eq guid'" + accountId + "' and Record2Id/Id eq guid'" + contactId + "' and EffectiveEnd eq null"; // 调用SDK REST接口查询记录 SDK.REST.retrieveMultipleRecords( entityType, queryOptions, function(queryResults) { // 如果查询到有效记录,说明已有未结束的关联,阻止操作 if (queryResults.length > 0) { Xrm.Page.ui.setFormNotification("该员工当前已与该公司存在有效关联,无法重复创建未结束的关联。", "ERROR", "DuplicateConnectionError"); // 阻止表单保存(如果是在保存前验证) Xrm.Page.data.entity.save = function() { return false; }; } else { // 清除之前的错误通知(如果存在) Xrm.Page.ui.clearFormNotification("DuplicateConnectionError"); } }, function(error) { console.error("验证关联记录时出错: ", error.message); Xrm.Page.ui.setFormNotification("验证关联时发生错误,请重试。", "ERROR", "ConnectionValidationError"); } ); }
关键细节说明
- 用Guid过滤而非名称:
直接使用实体Id过滤不仅避免了重名导致的错误,还能大幅提升查询效率,这是CRM OData查询的最佳实践。注意要去掉Id值自带的{}括号,OData接受的是纯Guid字符串。 - 正确的EntityReference过滤语法:
对于关联实体的Id过滤,语法是Record1Id/Id eq guid'[Guid值]',必须明确指定/Id属性并包裹guid关键字。 - EffectiveEnd的空值判断:
要筛选未结束的关联,用EffectiveEnd eq null;如果要筛选已结束的关联,则用EffectiveEnd ne null,完全符合你的业务需求。 - 表单交互处理:
查询结果返回后,通过表单通知提示用户,并覆盖save方法阻止无效的保存操作,确保验证逻辑生效。
内容的提问来源于stack exchange,提问作者PeeKay7
相关产品推荐
相关产品推荐

