Dynamics CRM插件多记录字段求和:零值差异化处理与公式存储
调整方案
核心问题是现有逻辑把最终求和结果是否为0作为执行字段更新、创建公式记录的判断条件,无法区分两种零值场景。正确的判断依据应该是计算过程中是否存在非零的源字段值参与,而非最终的求和结果。
实现步骤
- 每个待计算属性的遍历循环内,新增布尔标记
hasAnyNonZeroValue,初始值为false,用于记录当前属性的计算过程中是否出现过非零的源值。 - 成功解析到源字段的数值
attrValue后,增加判断:只要attrValue != 0,就将hasAnyNonZeroValue设为true。 - 将原逻辑中
if (fieldSum != 0)的判断条件,替换为if (hasAnyNonZeroValue)——只要有非零值参与计算,不管最终求和结果是多少,都正常执行字段更新、公式记录创建逻辑;如果所有源字段值都是空、0,哪怕求和结果也是0,直接跳过后续操作。
调整后的核心代码
foreach (var attribute in attributeList) { Decimal fieldSum = 0; string computedNote = string.Empty; // 新增:标记当前属性计算过程中是否存在非零源值 bool hasAnyNonZeroValue = false; foreach (var entity in mainEntityList) { if (entity.Contains(attribute)) { if (entity.Attributes[attribute] != null) { string type = entity.Attributes[attribute].GetType().Name; Decimal attrValue = 0; if (type == "AliasedValue") { AliasedValue aliasedFieldValue = (entity.GetAttributeValue<AliasedValue>(attribute)); attrValue = aliasedFieldValue.Value.GetType().Name == "Decimal" ? (Decimal)aliasedFieldValue.Value : Convert.ToDecimal(aliasedFieldValue.Value); } else { attrValue = entity.Attributes[attribute].GetType().Name == "Decimal" ? entity.GetAttributeValue<Decimal>(attribute) : Convert.ToDecimal(entity.Attributes[attribute]); } fieldSum += attrValue; // 优化公式拼接:保留原始数值精度,不再强制转Int32 computedNote += $"+{attrValue}"; // 标记非零值参与 if (attrValue != 0) { hasAnyNonZeroValue = true; } } } else { computedNote += $"+0"; } } // 替换原有的求和结果判断,改为判断是否有非零值参与计算 if (hasAnyNonZeroValue) { Entity formula = new Entity("formula"); string entityName = string.Empty; string attributeName = attribute.Trim(); // 提前清洗属性名的尾随空格 Guid recordId = Id; // 原有字段赋值逻辑保持不变 if (attribute.Contains("opportunity")) { opportunity[attributeName] = fieldSum; entityName = Opportunity.EntityLogicalName; } else if (attribute.Contains("contact")) { contact[attributeName] = fieldSum; entityName = Contact.EntityLogicalName; } else { mainentity[attributeName] = fieldSum; entityName = mainEntity.EntityLogicalName; } // 原有公式记录赋值逻辑保持不变 formula.Attributes["ice_entity"] = entityName; formula.Attributes["ice_attribute"] = attributeName; formula.Attributes[$"{entityName}id"] = new EntityReference(entityName, recordId); // 拼接公式字符串,去掉开头多余的+号 formula.Attributes["ice_computednote"] = computedNote.Remove(0, 1); requestsCollection.Entities.Add(formula); } } requestsCollection.Entities.Add(opportunity); requestsCollection.Entities.Add(contact); requestsCollection.Entities.Add(mainentity);
场景适配验证
对照业务示例的数值,调整后的逻辑完全匹配要求:
- Price字段:源值500、200,触发非零标记,求和700,正常更新字段、生成公式
500+200 - Quantity字段:源值25、10,触发非零标记,求和35,正常更新字段、生成公式
25+10 - contact.revenue字段:源值100、100,触发非零标记,求和200,正常更新字段、生成公式
100+100 - opportunity.sales字段:源值10000、-10000,触发非零标记,虽然最终求和为0,仍然正常更新字段、生成公式
10000+-10000(可通过简单的字符串替换优化为10000 + (-10000)的展示格式) - Volume字段:源值全为0,未触发非零标记,直接跳过,不更新字段、不创建公式记录
附带优化点
- 原代码中强制将数值转Int32的写法会丢失小数精度,调整为直接保留Decimal类型的原始值进行公式拼接,匹配实际业务的数值类型
- 原
AttributeList中"price "存在尾随空格,调整后对属性名做Trim处理,避免实体属性匹配失败 - 公式拼接逻辑可扩展负值的展示格式,提升公式的可读性
内容的提问来源于stack exchange,提问作者MVC_Nhibernate
相关产品推荐
相关产品推荐

