2014-02-17 110 views
1

我有一個自定義工作流活動,刪除自定義實體上運行。
我需要確定刪除消息是否是從父實體(商機)的常規刪除或級聯刪除。
動態CRM檢測,如果刪除消息是級聯刪除

我發現即使存在級聯刪除,父實體也存在。

我還有什麼可以看看是否刪除是級聯刪除的結果?

我需要得到這個信息,因爲自定義實體正在更新刪除的父實體 - 它應該只會在刪除不是級聯刪除的結果時更新,否則會發生SQL錯誤,可能是由於到工作流嘗試更新在事務中被刪除的記錄這一事實。

編輯

唐基牛逼asked the same question here,但它並沒有解決。

回答

1

我結束了

  • 更改關係指涉
  • 並稱,在變化的子實體查找到它的執行異步工作流的父
  • 查找是強制性
  • 的工作流程檢查字段是否爲空,並且如果它是

這個自定義工作流活動刪除當前記錄:

public class DeleteCurrentRecord : CodeActivity 
{ 
    protected override void Execute(CodeActivityContext context) 
    { 
     if (context == null) 
     { 
      throw new InvalidPluginExecutionException("Workflow context error. Please retry the operation."); 
     } 
     using (var workflowContext = new WorkflowContext(context)) 
     { 
      DeleteRecord(workflowContext, context); 
     } 
    } 
    public void DeleteRecord(WorkflowContext context, CodeActivityContext activityContext) 
    { 
     var targetId = context.Target != null ? context.Target.Id : context.TargetReference.Id; 
     var targetName = context.Target != null ? context.Target.LogicalName : context.TargetReference.LogicalName; 
     context.Service.Delete(targetName, targetId); 
    } 
} 

這是我寫的那得到的一切我從CodeActivityContext需要的輔助類。
它只是節省了爲每個工作流程編寫相同的鍋爐板代碼。
我也可以構造一個對象在控制檯應用程序在本地測試工作流程:

/* WorkflowContext is a helper class that I wrote that gets all the CRM services 
* and everything else from a CodeActivityContext 
* I then pass an instance of it to methods 
* I add properties to WorkflowContext as needed 
* */ 
/* Contains objects that are taken from CodeActivityContext 
* */ 
public class WorkflowContext : IDisposable 
{ 
    public IOrganizationService Service { get; private set; } 
    public Entity Target { get; private set; } 
    public EntityReference TargetReference { get; private set; } 
    public Context Linq { get; private set; } 
    public IWorkflowContext CurrentContext { get; set; } 
    public string PrimaryEntityName { get; set; } 
    public int Depth { get; set; } 
    public WorkflowContext(CodeActivityContext activityContext) 
    { 
     IWorkflowContext context = activityContext.GetExtension<IWorkflowContext>(); 
     CurrentContext = context; 
     PrimaryEntityName = context.PrimaryEntityName; 
     Depth = context.Depth; 
     IOrganizationServiceFactory factory = activityContext.GetExtension<IOrganizationServiceFactory>(); 
     if (context.InputParameters.Contains("Target")) // On demand workflows do not have target 
     { 
      if (context.InputParameters["Target"].GetType() == typeof(Entity)) 
       Target = (Entity)context.InputParameters["Target"]; 
      else if (context.InputParameters["Target"].GetType() == typeof(EntityReference)) // delete and some other operations are EntityReference 
       TargetReference = (EntityReference)context.InputParameters["Target"]; 
     } 
     Service = factory.CreateOrganizationService(context.InitiatingUserId); 
     Linq = new Context(Service); 
    } 
    // Constructor for testing 
    public WorkflowContext(IOrganizationService service, Context linq, EntityReference targetReference, Entity target, bool inTransaction) 
    { 
     this.Service = service; 
     this.Linq = linq; 
     this.TargetReference = targetReference; 
     this.Target = target; 
    } 
    public void Dispose() 
    { 
     Linq.Dispose(); 
    } 
} 
1

我相信你可以檢查工作流上下文的ParentContext成員。如果它爲null或ParentContext的消息不等於Delete - 這意味着這不是級聯刪除。檢查this article

+0

謝謝你的答案。我試了一下,發現ParentContext對於父實體的刪除和級聯刪除都是空的。你能指點我其他方向嗎? – Bvrce

+0

在這種情況下,我會建議使用異步插件而不是工作流。 –

1

將您的工作流程改爲插件,那麼您應該可以使用Plugin Shared Variables來確定該信息。只需將Pre事件插件添加到父實體,即指定這是父級聯刪除的一部分。然後在子插件中,檢查該變量是否存在,如果它不知道它不是級聯。

+0

共享變量在兩個計數上都不存在 - 當手動刪除記錄時(這是預期的),而且當通過級聯刪除父記錄刪除記錄時;對於兩次刪除,父上下文都爲空。 – Bvrce

+0

哦,等等,出於某種原因,我認爲這是一個插件。由於這是一個工作流程,所以不起作用。@Brrce,如果您將其更改爲插件而不是工作流程,則可以使用此工具。 – Daryl

+0

我能夠在IWorkflowContext中定義一個共享變量。我認爲它不會與插件兼容 - Tanguy嘗試使用插件。似乎有級聯刪除的問題。 – Bvrce