2013-08-31 71 views
0

我正在爲自定義實體(OpportunityService)開發更新插件。我的目標是比較更新前後的數據。這就是爲什麼我註冊了Pre圖像和Post圖像類型的實體圖像。圖像的名稱是OpportunityService,別名也是OpportunityService。CRM 2011插件:實體圖像:KeyNotFoundException

然後在我的代碼中,我試圖讓這些圖像,以便我可以檢查是否有一些字段被更改,如果他們是我會執行一些操作。但這不在我的問題範圍之內。

我想是指實體圖像如下

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

但在這一點上我的插件拋出System.Collections.Generic.KeyNotFoundException。

「Business Process Error。來自插件的意外異常(Execute):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()); } 
     } 
    } 
} 

我的插件在術後階段(更新消息)同步註冊。

我在這裏做錯了,我看不到?

預先感謝您。

編輯:這裏的答案

謝謝你的答案。通過閱讀他們,並試圖找出什麼是錯的,我終於明白,這個問題是不是在所有的實體圖像,但這一行:

EntityReference opportunityReference = (EntityReference)opportunityService.Attributes["mpc_opportunityid"]; 

,是因爲它是更新的消息,並將其返回只改值的「目標」的「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()); } 

和現在的作品...

回答

1

你能準確指出哪一行你會得到這個異常嗎?

您可以在獲取圖像的位置獲取圖像,還可以獲取mpc_monthlyprice,mpc_startprice和mpc_estinvoicingperyear的值。當它們中的任何一個爲空時,屬性將不會被添加到opportunityService對象中,並且在嘗試檢索時會發生異常。

+0

問題發生在這一行: 實體preOpportunityService =(實體)context.PreEntityImages [「OpportunityService」]; 我甚至從代碼中拿走了這三個錢幣字段,因爲我們可以在解決這個問題後從圖像中獲得金錢價值。 – kivikall

+0

您可以驗證圖像是否正確註冊?即string registredkeys =「Registered pre images:」+ String.Join(「,」,context.PreEntityImages.Keys);並將此字符串的異常作爲錯誤消息拋出。 – MarioZG

+0

謝謝你的回答。我找到了答案。我很抱歉誤導我的第一個答覆。我在原來的帖子中添加了答案。 – kivikall

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

隨着CRM的後期綁定數據模型,這個語句的上方將引發「密鑰找不到」錯誤,如果在CRM中的「OpportunityService」字段中沒有任何實際價值。所以這基本上意味着這個領域沒有任何東西。

您可以手動檢查您嘗試爲null提取的每個屬性,也可以只使用crmsvcutil並自動生成您的CRM模型。這會給你一個強類型模型,你不必擔心對屬性的空檢查。

+0

您可能需要嘗試再次爲我解釋:)如果我在插件註冊工具中創建實體圖像,在哪種情況下它們可以爲空?我認爲(在這種情況下),每當我更新我的OpportunityService實體時,即使我要求的值沒有改變,它也會爲我提供Pre和Post實體圖像?即使我更新了所有我正在提取的值,我也會得到同樣的錯誤... – kivikall

+0

是否存在沒有實體圖像的情況? 「前」條件是沒有圖像存在的情況? – Thousand

+0

據我所知,答案是否定的,因爲我的插件已在更新步驟/更新消息(發佈操作)中註冊。 – kivikall

0

使用context.InputParameters [「Target」]你得到一個實體。該實體只包含已更改的屬性。

0

我知道這是舊的文章,但實體,像那些你從PreEntityImages,PostEntityImages,並像「機會」強類型類InputParameters得到轉換,使用擴展方法:

.ToEntity<opportunity>()