You need to enable JavaScript to run this app.
优惠活动
大模型
产品
解决方案
定价
更多

Dataverse插件Update消息报错:给定的键不在字典中

问题原因

Dataverse插件触发Update消息时,默认传入的entity对象仅包含本次被修改的字段,而非完整实体。如果本次更新未改动stagingtype字段,直接通过entity["stagingtype"]取值就会触发「键不存在」的错误。而Create消息时传入的是完整实体,所以不会有这个问题。

另外原代码还有个隐藏问题:Update时查询重复会把当前记录本身算进去,导致误判重复。

解决方法

推荐直接获取完整实体来避免字段缺失问题,同时修正查询逻辑排除当前记录:

修改后的完整代码

if (entity.LogicalName == "atmtransaction")
{
    tracingService.Trace("Stage {0}", "1");
    
    // 获取当前实体的ID
    Guid recordId = ((EntityReference)context.InputParameters["Target"]).Id;
    // 从Dataverse获取完整的实体记录,指定需要的字段
    Entity fullEntity = service.Retrieve("atmtransaction", recordId, new ColumnSet("stagingtype", "store", "date"));
    
    tracingService.Trace("Stage {0}", "2");
    OptionSetValue stagingType = (OptionSetValue)fullEntity["stagingtype"];
    tracingService.Trace("Stage {0}", "3");

    string store = (string)fullEntity["store"];
    tracingService.Trace("Stage {0}", "4");

    DateTime date = (DateTime)fullEntity["date"];
    tracingService.Trace("Stage {0}", "5");

    if (stagingType.Value != 1)
    {
        tracingService.Trace("Stage {0}", "6");
        // 检查重复:排除当前更新的记录本身
        QueryExpression query = new QueryExpression("ada_atmtransaction");
        query.Criteria.AddCondition("ada_store", ConditionOperator.Equal, store);
        query.Criteria.AddCondition("ada_date", ConditionOperator.Equal, date);
        query.Criteria.AddCondition("ada_atmtransactionid", ConditionOperator.NotEqual, recordId);

        EntityCollection results = service.RetrieveMultiple(query);
        if (results.Entities.Count > 0)
        {
            tracingService.Trace("Stage {0}", "7");
            throw new InvalidPluginExecutionException("A record already exists with the same store and date.");
        }
     }
}

关键修改点

  • 获取完整实体:通过service.Retrieve指定需要的字段(stagingtype、store、date),确保无论字段是否被修改都能拿到值。
  • 排除当前记录:在查询条件中添加ada_atmtransactionid != 当前记录ID,避免Update时误判自身为重复记录。

备选方案(仅处理单个字段)

如果不想获取完整实体,可以单独检查字段是否存在,不存在则从数据库查询该字段:

OptionSetValue stagingType;
Guid recordId = ((EntityReference)context.InputParameters["Target"]).Id;

if (entity.Contains("stagingtype"))
{
    stagingType = (OptionSetValue)entity["stagingtype"];
}
else
{
    // 仅查询stagingtype字段
    Entity existingRecord = service.Retrieve("atmtransaction", recordId, new ColumnSet("stagingtype"));
    stagingType = (OptionSetValue)existingRecord["stagingtype"];
}

但这种方法需要对每个可能缺失的字段做判断,不如直接获取完整实体简洁可靠。

内容的提问来源于stack exchange,提问作者liam

相关产品推荐
方舟 Agent Plan

超全模态模型 × Harness 升级,最新支持 Deepseek-V4.1-Flash、GLM-5.3 系列、Doubao-Seedream-5.0-pro、Kimi-K3 (部分), 限时 9.9 元起

最近更新时间:2026.07.16 23:27:39