2014-02-15 32 views
2

我有一個插件在預刪除操作時觸發。在插件內部,我需要運行一個linq查詢來獲取與插件觸發的實體相關的另一個實體的guid列表。Linq查詢(預刪除操作)插件

當在這個插件中使用我的查詢時,它不會取回任何數據,但是當我從後更新操作插件運行相同的查詢時,它會返回數據。

我不確定問題是否與預刪除操作或其他相關。 請注意,EntityA是插件觸發的實體。

這裏是我的代碼,我也非常感謝你的幫助:

using (var serviceContext = new OrganizationServiceContext(service)) 
      { 
       Entity bEntity = new Entity("EntityB"); 
       serviceContext.AddObject(bEntity); 

      var qTr = from n in serviceContext.CreateQuery<EntityB>() 
      where n.field.Id.Equals(new Guid(EntityAGuid.ToString())) 
          select n.EntityBguid; 

       foreach (var trGuid in qTr) 
       { 
        service.Delete("EntityB", (Guid)trGuid); 
       } 
      } 
+0

如果我使用後刪除操作我的插件我收到以下錯誤:**錯誤PostPluginDelete插件:System.ServiceModel.FaultException'1 [Microsoft.Xrm.Sdk.OrganizationServiceFault]:EntityA隨着Id = 2zdd8418-7793-e311-5537-555556836fb7不存在(故障詳細信息等於Microsoft.Xrm.Sdk.OrganizationServiceFault)。** – Nick

+0

當我在預驗證階段註冊我的插件時。它工作正常。 – Nick

+0

你有沒有找到這個解決方案? – LameCoder

回答

1

如果你想編寫一個需要讀取被刪除記錄子項的插件 - 這必須在預驗證階段完成。

這是爲什麼?

對於與刪除行爲的1:N關係行爲:刪除鏈接,被刪除的父對查找在階段10(預驗證)和20(預操作)之間的某處設置爲空,但在主要記錄的事務中刪除。

因此,如果想在任何階段預驗證後,你不會得到任何結果,因爲它們都具有其中關係歸零一個尚未提交的更新事務中獲取的孩子們。

我到底爲什麼要在乎?

您可能會同意我的觀點,即關於級聯關係行爲的限制並不能完全滿足創建手動N:N關係時的常見需求。

https://community.dynamics.com/crm/b/cinterosab_crmblog/archive/2012/10/02/crm-plugins-retrieve-children-during-delete.aspx

0

我猜你是不是創建IOrganisationalService從插件上下文,但建立一個OrganizationServiceProxy。這有兩個原因是不好的。

  1. 您已經在服務器上,並將另一個WCF呼叫發送到同一臺服務器。
  2. 此外部調用在數據庫事務之外。這就是實體不存在的原因。
+0

感謝Daryl的迴應。其實我從我的插件'IPluginExecutionContext context = localContext.PluginExecutionContext使用IOrganizationService; IOrganizationService service = localContext.OrganizationService;' – Nick

+0

任何人都可以解釋一下嗎? – Nick

0

所以這不是理想的,但這對我很有用。你需要兩個插件。預驗證以及預操作或後操作(選擇是您的)。

需要注意的是,你需要在操作前或後操作插件使用ParentContext是很重要的。就在這個博客上發現SharedVariables

更多信息:http://thomasthankachan.com/2011/08/12/pass-data-between-plug-ins-using-sharedvariables/

操作步驟如下:

protected void PreValidate(LocalPluginContext localContext) 
{ 
    IPluginExecutionContext context = localContext.PluginExecutionContext;     
    IOrganizationService service = localContext.OrganizationService; 

    using (var serviceContext = new OrganizationServiceContext(service)) 
    { 
     Entity bEntity = new Entity("EntityB"); 
     serviceContext.AddObject(bEntity); 

     var qTr = from n in serviceContext.CreateQuery<EntityB>() 
     where n.field.Id.Equals(new Guid(EntityAGuid.ToString())) 
         select n.EntityBguid; 

     List<Guid> guids = new List<Guid>(); 
     foreach (var trGuid in qTr) 
     { 
      guids.Add((Guid)trGuid); 
     } 

     context.SharedVariables.Add("GuidsToDelete", guids); 
    } 
} 

protected void PostOperation(LocalPluginContext localContext) 
{ 
    object o; 
    if(localContext.PluginExecutionContext.ParentContext.SharedVariables.TryGetValue("GuidsToDelete", out o)) 
    { 
     List<Guid> guids = (List<Guid>)o; 
     foreach(var g in guids) 
     { 
      localContext.OrganizationService.Delete("EntityB", (Guid)trGuid); 
     } 
    } 
} 
0

如果你正在運行的刪除消息的預操作事件的一個插件,有一點要注意那時候,CRM已經與任何兒童記錄分離了記錄。因此,如果您需要查詢與該記錄相關的任何子記錄,則不會從您的查詢中返回。

解決的辦法是登記在預驗證事件的插件。 http://mscrmdev.blogspot.ca/2012/02/pre-delete-plugin-gotcha.html