Linq查询(预删除操作)插件

时间:2014-02-15 00:13:16

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

我有一个插件可以在Pre Delete Operation上触发。在插件内部我需要运行一个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);
                }
           }

4 个答案:

答案 0 :(得分: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

答案 1 :(得分:0)

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

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

答案 2 :(得分:0)

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

需要注意的是,您需要在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);
        }
    }
}

答案 3 :(得分:0)

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

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