【问题标题】:Linq Query in a (Pre Delete Operation) Plugin(删除前操作)插件中的 Linq 查询
【发布时间】:2014-03-03 13:20:02
【问题描述】:

我有一个在预删除操作时触发的插件。在插件内部,我需要运行 linq 查询以获取与触发插件的实体相关的另一个实体的 guid 列表。

在此插件中使用我的查询时,它不会返回任何数据,但是当我从更新后操作插件运行相同的查询时,它会返回数据。

我不确定问题是否与预删除操作或其他问题有关。 请注意,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);
                }
           }

【问题讨论】:

  • 如果我对我的插件使用 Post Delete 操作,我会收到以下错误:PostPluginDelete PlugIn 中的错误:System.ServiceModel.FaultException`1[Microsoft.Xrm.Sdk.OrganizationServiceFault]:EntityA Id = 2zdd8418-7793-e311-5537-555556836fb7 不存在(故障详细信息等于 Microsoft.Xrm.Sdk.OrganizationServiceFault)。
  • 当我在预验证阶段注册我的插件时。它工作正常。
  • 您找到解决方案了吗?
  • 我正在做一件非常相似的事情,根据 Daryl 的回答,它可能与单独的上下文有关,我将 LINQ 查询转换为查询表达式并直接使用插件的上下文。仍然没有结果。如果这确实是一个 PRE 操作,那么该项目不应该被删除。虽然看起来引用已经以某种方式断开了。
  • 我尝试使用 Pre-Validation 事件在 PluginExecutionContext 上添加有关对 SharedVariables 的旧引用的信息。但是,Pre-Operation 事件似乎具有一组全新的共享变量,因为列表始终为空。我真的很好奇 Pre-Operation 中实际发生了什么,因为如果实体实际上在删除之前,它应该仍然存在。

标签: linq dynamics-crm-2011 dynamics-crm


【解决方案1】:

如果您想编写一个需要读取被删除记录的子项的插件 - 这必须在预验证阶段完成。

这是为什么呢?

对于具有删除行为的 1:N 关系:删除链接,对正在删除的父项的查找设置为 null 阶段 10(预验证)和 20(预操作)之间的某个位置,但在主记录删除的事务中.

因此,如果在预验证之后的任何阶段尝试检索子项,您都不会得到任何结果,因为它们都有一个尚未提交的更新事务,其中关系为空。

我到底为什么要关心?

您可能同意我的观点,即关系上的级联行为的约束并不能完全满足创建手动 N:N 关系时非常常见的需求。

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

【讨论】:

    【解决方案2】:

    我猜你不是从插件上下文创建IOrganisationalService,而是创建OrganizationServiceProxy。这有两个原因。

    1. 您已经在服务器上并且正在对同一服务器进行另一个 WCF 调用。
    2. 此外部调用在数据库事务之外。这就是实体不存在的原因。

    【讨论】:

    • 感谢达里尔的回复。实际上我正在使用我的插件中的 IOrganizationService IPluginExecutionContext context = localContext.PluginExecutionContext; IOrganizationService service = localContext.OrganizationService;
    • 谁能解释一下?
    【解决方案3】:

    所以这并不理想,但这对我有用。你需要两个插件。预验证以及操作前或操作后(由您选择)。

    需要注意的是,您需要在 Pre-Operation 或 Post-Operation 插件中使用 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);
            }
        }
    }
    

    【讨论】:

      【解决方案4】:

      如果您在删除消息的操作前事件上运行插件,需要注意的一点是,到那时 CRM 已经取消了上下文中的记录与任何子记录的关联。因此,如果您需要查询与该记录相关的任何子记录,您的查询将不会返回任何内容。

      解决此问题的方法是在预验证事件中注册您的插件。 http://mscrmdev.blogspot.ca/2012/02/pre-delete-plugin-gotcha.html

      【讨论】:

        猜你喜欢
        • 2021-06-04
        • 1970-01-01
        • 2020-07-11
        • 1970-01-01
        • 1970-01-01
        • 1970-01-01
        • 1970-01-01
        • 1970-01-01
        • 1970-01-01
        相关资源
        最近更新 更多