我正在为自定义实体(OpportunityService)开发一个更新插件。我的目标是比较更新前后的数据。这就是我为Pre图像和Post图像类型注册实体图像的原因。图像的名称是OpportunityService,别名也是OpportunityService。
然后在我的代码中,我试图获取这些图像,以便我可以检查某些字段是否已更改,如果是,我会执行某些操作。但这不在我的问题范围内。
我正在尝试如下引用实体图像
Entity preOpportunityService = (Entity)context.PreEntityImages["OpportunityService"];
Entity postOpportunityService = (Entity)context.PostEntityImages["OpportunityService"];
但是在那一点上我的插件会抛出System.Collections.Generic.KeyNotFoundException。
“业务流程错误。插件出现意外异常(执行):OpportunityServicePlugin.OpportunityServiceCalculatorOnUpdate: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()); }
}
}
}
我的插件同步在Post操作阶段(Update message)注册。
我在这里做错了,我看不到?
提前谢谢。
编辑:这是答案
谢谢你的回答。通过阅读它们并试图弄清楚什么是错的,我终于明白问题不在于实体图像,而在于这条线:
EntityReference opportunityReference = (EntityReference)opportunityService.Attributes["mpc_opportunityid"];
因为它是Update消息,它只返回“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()); }
现在它有效......
答案 0 :(得分:1)
你能确切地指出你得到这个例外的确切线路吗?
你可以在获得图像的地方获取它们,但也可以获得mpc_monthlyprice,mpc_startprice和mpc_estinvoicingperyear的值。如果其中任何一个为null,则不会将属性添加到opportunityService对象,并且在尝试检索它时会出现异常。
答案 1 :(得分:0)
Entity postOpportunityService = (Entity)context.PostEntityImages["OpportunityService"];
使用CRM中的后期绑定数据模型,如果CRM中的“OpportunityService”字段没有实际值,则上述语句将抛出“Key not found”错误。所以这基本上意味着该领域没有任何内容。
您可以手动检查您尝试获取的每个属性为null,或者您可以使用crmsvcutil并自动生成您的CRM模型。这将为您提供强类型模型,您不必再担心属性的空检查。
答案 2 :(得分:0)
使用context.InputParameters [“Target”]获得一个实体。该实体仅包含已更改的属性。
答案 3 :(得分:0)
我知道这是一篇旧帖子,但要将实体(如从PreEntityImages,PostEntityImages和InputParameters获得的实体转换为类似“机会”的强类型类),请使用扩展方法:
.ToEntity<opportunity>()