Warning: file_get_contents(/data/phpspider/zhask/data//catemap/8/linq/3.json): failed to open stream: No such file or directory in /data/phpspider/zhask/libs/function.php on line 167

Warning: Invalid argument supplied for foreach() in /data/phpspider/zhask/libs/tag.function.php on line 1116

Notice: Undefined index: in /data/phpspider/zhask/libs/function.php on line 180

Warning: array_chunk() expects parameter 1 to be array, null given in /data/phpspider/zhask/libs/function.php on line 181
(预删除操作)插件中的Linq查询_Linq_Dynamics Crm 2011_Dynamics Crm - Fatal编程技术网

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

(预删除操作)插件中的Linq查询,linq,dynamics-crm-2011,dynamics-crm,Linq,Dynamics Crm 2011,Dynamics Crm,我有一个插件,在预删除操作时触发。在插件内部,我需要运行一个linq查询,以获取与触发插件的实体相关的另一个实体的GUID列表 当在这个插件中使用我的查询时,它不会返回任何数据,但当我从更新后操作插件运行相同的查询时,它会返回数据 我不确定问题是否与预删除操作或其他相关。 请注意EntityA是插件触发的实体 这是我的代码,非常感谢您的帮助: using (var serviceContext = new OrganizationServiceContext(service))

我有一个插件,在预删除操作时触发。在插件内部,我需要运行一个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);
                }
           }
使用(var-servicecoxt=new-organizationservicecoxt(服务))
{
实体本提=新实体(“实体B”);
serviceContext.AddObject(bEntity);
var qTr=来自serviceContext.CreateQuery()中的n
其中n.field.Id.Equals(新Guid(EntityAGuid.ToString()))
选择n.EntityBguid;
foreach(qTr中的变量trGuid)
{
删除(“EntityB”,(Guid)trGuid);
}
}

我猜您不是从插件上下文创建您的
iorganionalservice
,而是创建一个
OrganizationServiceProxy
。这不好有两个原因

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

  • 所以这并不理想,但对我来说很有效。你需要两个插件。预验证和预操作或后操作(由您选择)

    需要注意的是,您需要在操作前或操作后插件中使用ParentContext

    有关此博客上的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);
            }
        }
    }
    
    protectedvoidprevalidate(localpluginontext localContext)
    {
    IPluginExecutionContext context=localContext.PluginExecutionContext;
    IOOrganizationService=localContext.OrganizationService;
    使用(var serviceContext=新组织serviceContext(服务))
    {
    实体本提=新实体(“实体B”);
    serviceContext.AddObject(bEntity);
    var qTr=来自serviceContext.CreateQuery()中的n
    其中n.field.Id.Equals(新Guid(EntityAGuid.ToString()))
    选择n.EntityBguid;
    List guids=new List();
    foreach(qTr中的变量trGuid)
    {
    添加((Guid)trGuid);
    }
    context.SharedVariables.Add(“guidsodelete”,guids);
    }
    }
    受保护的void PostOperation(LocalPluginContext localContext)
    {
    对象o;
    if(localContext.PluginExecutionContext.ParentContext.SharedVariables.TryGetValue(“guidsodelete”,out o))
    {
    列表guids=(列表)o;
    foreach(guids中的变量g)
    {
    localContext.OrganizationService.Delete(“EntityB”,(Guid)trGuid);
    }
    }
    }
    
    如果您在删除消息的预操作事件上运行插件,需要注意的一点是,此时CRM已将上下文中的记录与任何子记录解除关联。因此,如果需要查询与该记录相关的任何子记录,则查询不会返回任何结果

    解决这个问题的方法是在预验证事件中注册插件。

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

    为什么呢

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

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

    我到底为什么要在乎

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


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