Dynamics crm 2011 CRM 2011插件:实体映像:KeyNotFoundException

Dynamics crm 2011 CRM 2011插件:实体映像:KeyNotFoundException,dynamics-crm-2011,dynamics-crm,Dynamics Crm 2011,Dynamics Crm,我正在为我的自定义实体(OpportunityService)开发一个更新插件。我的目标是比较更新前后的数据。这就是为什么我为Pre-image和Post-image类型注册了一个实体图像。映像的名称是OpportunityService,别名也是OpportunityService 然后在我的代码中,我尝试获取这些图像,以便检查一些字段是否更改,如果更改,我将执行一些操作。但这不在我的问题范围之内 我试图引用实体图像,如下所示 Entity preOpportunityService = (E

我正在为我的自定义实体(OpportunityService)开发一个更新插件。我的目标是比较更新前后的数据。这就是为什么我为Pre-image和Post-image类型注册了一个实体图像。映像的名称是OpportunityService,别名也是OpportunityService

然后在我的代码中,我尝试获取这些图像,以便检查一些字段是否更改,如果更改,我将执行一些操作。但这不在我的问题范围之内

我试图引用实体图像,如下所示

Entity preOpportunityService = (Entity)context.PreEntityImages["OpportunityService"];
Entity postOpportunityService = (Entity)context.PostEntityImages["OpportunityService"];
但在这一点上,我的插件抛出System.Collections.Generic.KeyNotFoundException

“业务流程错误。插件(执行)出现意外异常:OpportunityServicePlugin.OpportunityServiceCalculatorUnUpdate:System.Collections.Generic.KeyNotFoundException:字典中不存在给定的密钥。”

我目前的完整代码如下所示:

using System;
using System.ServiceModel;
using System.Collections.Generic;
using System.Linq;
using System.Text;
using Microsoft.Xrm.Sdk;
using Microsoft.Xrm.Sdk.Query;

namespace OpportunityServicePlugin
{
    public class OpportunityServiceCalculatorOnUpdate: IPlugin
    {
        public void Execute(IServiceProvider serviceProvider)
        {

            // General plugin components 

            IPluginExecutionContext context = (IPluginExecutionContext)serviceProvider.GetService(typeof(IPluginExecutionContext));
            IOrganizationServiceFactory factory = (IOrganizationServiceFactory)serviceProvider.GetService(typeof(IOrganizationServiceFactory));
            IOrganizationService service = factory.CreateOrganizationService(context.UserId);
            ITracingService tracingService = (ITracingService)serviceProvider.GetService(typeof(ITracingService));

            try
            {
                // Current opportunity service
                Entity opportunityService = (Entity)context.InputParameters["Target"];

                // Opportunity service's parent opportunity lookup reference
                EntityReference opportunityReference = (EntityReference)opportunityService.Attributes["mpc_opportunityid"];

                // Columns to be retrieved for opportunity (aka. columns to be edited)
                ColumnSet opportunityColumnSet = new ColumnSet(new string[] { "estimatedvalue", "mpc_estoneoffinvoicing", "mpc_estinvoicingperyear" });

                // Retrieve actual opportunity entity
                Entity opportunity = service.Retrieve(opportunityReference.LogicalName, opportunityReference.Id, opportunityColumnSet);

                // Opportunity service's money fields
                Money monthlyPrice = (Money)opportunityService["mpc_monthlyprice"];
                Money oneOffPrice = (Money)opportunityService["mpc_startprice"];
                Money estInvoicingPerYear = (Money)opportunityService["mpc_estinvoicingperyear"];

                Entity preOpportunityService = (Entity)context.PreEntityImages["OpportunityService"];
                Entity postOpportunityService = (Entity)context.PostEntityImages["OpportunityService"];

            }
            catch (FaultException<OrganizationServiceFault> ex) { tracingService.Trace("FaultException", ex.ToString()); }
        }
    }
}
因此,因为它是更新消息,并且只返回“Target”的更改值,“mpc_opportunityid”是这里的实际问题--

我将代码更改为以下内容

try
{
    Entity preOpportunityService = (Entity)context.PreEntityImages["OpportunityService"];
    Entity postOpportunityService = (Entity)context.PostEntityImages["OpportunityService"];

    // Opportunity service's parent opportunity lookup reference
    EntityReference opportunityReference = (EntityReference)postOpportunityService.Attributes["mpc_opportunityid"];

    // Columns to be retrieved for opportunity (aka. columns to be edited)
    ColumnSet opportunityColumnSet = new ColumnSet(new string[] { "estimatedvalue", "mpc_estoneoffinvoicing", "mpc_estinvoicingperyear" });

    // Retrieve actual opportunity entity
    Entity opportunity = service.Retrieve(opportunityReference.LogicalName, opportunityReference.Id, opportunityColumnSet);             

}
catch (FaultException<OrganizationServiceFault> ex) { tracingService.Trace("FaultException", ex.ToString()); }
试试看
{
实体preOpportunityService=(实体)上下文。PreEntityImages[“OpportunityService”];
实体postOpportunityService=(实体)上下文。PostEntityImages[“OpportunityService”];
//Opportunity服务的父Opportunity查找引用
EntityReference opportunityReference=(EntityReference)postOpportunityService.Attributes[“mpc_opportunityid”];
//要为opportunity检索的列(也称为要编辑的列)
ColumnSet opportunityColumnSet=新列集(新字符串[]{“estimatedvalue”、“mpc_Estoneoffining”、“mpc_EstinVoicengPeryear”});
//检索实际商机实体
实体opportunity=service.Retrieve(opportunityReference.LogicalName、opportunityReference.Id、opportunityColumnSet);
}
catch(FaultException ex){tracingService.Trace(“FaultException”,ex.ToString());}

现在它工作了…

你能准确地指出你在哪一行得到这个异常吗

您可以在获取图像的地方获取它们,也可以在获取mpc_monthlyprice、mpc_startprice和mpc_EstinvoigPeryear的值的地方获取它们。当它们中的任何一个为null时,该属性将不会添加到opportunityService对象中,并且在尝试检索它时会出现异常

  Entity postOpportunityService = (Entity)context.PostEntityImages["OpportunityService"];
对于CRM中的后期绑定数据模型,如果CRM中的“OpportunityService”字段没有实际值,则上述语句将抛出“Key not found”错误。所以这基本上意味着这个领域里没有任何东西


您可以手动检查您试图获取的每个属性是否为null,也可以直接使用并自动生成CRM模型。这将为您提供一个强类型模型,您不再需要担心属性的空检查

使用context.InputParameters[“Target”]您将获得一个实体。此实体仅包含已更改的属性。

我知道这是一篇旧文章,但要将实体(如从PreEntityImages、PostEntityImages和InputParameters获得的实体)转换为强类型类(如“opportunity”),请使用扩展方法:

.ToEntity<opportunity>()
.ToEntity()

此行出现问题:Entity preOpportunityService=(Entity)context.PreEntityImages[“OpportunityService”];我甚至从代码中删除了这三个货币字段,因为在解决这个问题后,我可以从图像中获取货币值。您能验证图像是否正确注册吗?i、 e.string registeredkeys=“注册的预映像:”+string.Join(“,”,context.PreEntityImages.Keys);并将此字符串作为错误消息引发异常。谢谢您的回答。我找到了答案。很抱歉,我的第一个答复误导了你。我将答案添加到了我的原始帖子中。你可能需要再次为我解释:)如果我在插件注册工具中创建实体图像,在哪种情况下它们可以为空?我认为(在本例中)每当我更新我的OpportunityService实体时,它都会为我提供实体前和实体后的图像,即使我要求的值没有改变?即使我更新了所有获取的值,我也会遇到同样的错误……是否存在没有实体图像的情况?“前置”条件是不存在图像的情况?据我所知,答案是否定的,因为我的插件已在更新步骤/更新消息(后期操作)中注册。
.ToEntity<opportunity>()