【问题标题】:CRM 2013 Plugin not updating my fieldCRM 2013 插件未更新我的字段
【发布时间】:2014-07-17 17:03:18
【问题描述】:

我创建了一个 CRM 插件,它应该从子网格上的实体中获取值并保持运行总计。除了我正在查看的表单上的字段没有更新之外,一切似乎都正常工作。当我取消注释对 service.Update(entity) 的调用时,它给了我一个无限循环。关于我做错了什么的任何想法?到目前为止,我所看到的一切似乎都表明我的代码是正确的,所以我很茫然。谢谢。

using System;
using System.Collections.Generic;
using System.Linq;
using System.Text;
using System.IO;
using System.Net;
using System.Activities;
using Microsoft.Xrm.Sdk;
using Microsoft.Xrm.Sdk.Workflow;
using Microsoft.Xrm.Sdk.Query;
using Microsoft.Xrm.Sdk.Client;
using Microsoft.Xrm.Sdk.Messages;

namespace SubGrid_Calculator
{
public class SubgridCalculator : IPlugin
{
    //A list is a data structure that preserves the order of the elements that are put into it. 
    //A set is a data structure that does not allow duplicate objects. Order is NOT guaranteed in a set.
    //EntityReference returns 3 properties: Logical Name, ID and Name (often, but not always the primary key)

    IEnumerable<Entity> GetRelatedEntities(IOrganizationService service, string primaryEntity, Guid primaryEntityId, string relationshipName, string targetEntity)
    {
        //the related entity we are going to retrieve
        QueryExpression query = new QueryExpression();
        query.EntityName = targetEntity;
        query.ColumnSet = new ColumnSet("new_totalmonthlytext", "crmp_contract", "crmp_name");

        //the relationship that links the primary to the target
        Relationship relationship = new Relationship(relationshipName);
        relationship.PrimaryEntityRole = EntityRole.Referenced; //important if the relationship is self-referencing

        //the query collection which forms the request
        RelationshipQueryCollection relatedEntity = new RelationshipQueryCollection();
        relatedEntity.Add(relationship, query);

        //the request to get the primary entity with the related records
        RetrieveRequest request = new RetrieveRequest();
        request.RelatedEntitiesQuery = relatedEntity;
        request.ColumnSet = new ColumnSet("crmp_name");
        request.Target = new EntityReference(primaryEntity, primaryEntityId);

        RetrieveResponse r = (RetrieveResponse)service.Execute(request); //was service.Execute

        //query the returned collection for the target entity ids
        return r.Entity.RelatedEntities[relationship].Entities;//.Select(e => e.Id);
    }     

    private IOrganizationService orgService;
    private TraceServiceWrapper tracingService;

    public void Execute(IServiceProvider serviceProvider)
    {
        //Activity code
        Microsoft.Xrm.Sdk.IPluginExecutionContext context = (Microsoft.Xrm.Sdk.IPluginExecutionContext)
         serviceProvider.GetService(typeof(Microsoft.Xrm.Sdk.IPluginExecutionContext));

        IOrganizationServiceFactory serviceFactory = (IOrganizationServiceFactory)serviceProvider.GetService(typeof(IOrganizationServiceFactory));
        IOrganizationService service = serviceFactory.CreateOrganizationService(context.UserId);
        this.orgService = serviceFactory.CreateOrganizationService(context.UserId);
        OrganizationServiceContext ServiceContext = new OrganizationServiceContext(service);

        // The trace wrapper is a CRMPoint.net custom library for maching logging and tracing
        //TraceServiceWrapper trace = new TraceServiceWrapper(service, tracingService, "HttpTest"); NO idea what I'd need as my middle arg
        ITracingService tracingService = (ITracingService)serviceProvider.GetService(typeof(ITracingService));             //localContext.TracingService;

        var crmTracingService = (ITracingService)serviceProvider.GetService(typeof(ITracingService));

        if (crmTracingService == null)
        {
            throw new InvalidPluginExecutionException("Failed to retrieve the tracing service.");
        }
        this.tracingService = new TraceServiceWrapper(this.orgService, crmTracingService, "SubgridCalculator");


        if (context.InputParameters.Contains("Target") && context.InputParameters["Target"] is Entity)
        {
            // Obtain the target entity from the input parameters.
            Entity entity = (Entity)context.InputParameters["Target"];

            this.tracingService.Trace("Plugin Started!");
            this.tracingService.Trace("MEssage Name: ", context.MessageName);
            this.tracingService.Trace("Primary Entity Name: ", context.PrimaryEntityName);
            this.tracingService.Trace("Primary Entity Id: ", context.PrimaryEntityId );
            this.tracingService.Trace("PluginExecutionContext: ", context);
            this.tracingService.Trace("Post Context:");
            //this.tracingService.Trace(" ", );

            // Verify that the target entity represents an HttpTest entity
            if (entity.LogicalName != "crmp_contract") //was new_httptest
                return;
            this.tracingService.Trace("Entity is Plan:");

            //var preEntityImage = context.PreEntityImages["PreImage"];
            //this.tracingService.Trace("Preimage:", preEntityImage);
            //this.tracingService.Trace(TracingItemType.PreImage, EntityTraceHelper.TraceAttributes(preEntityImage));

            //var postEntityImage = context.PostEntityImages["PostImage"];
            //this.tracingService.Trace("POSTimage:", postEntityImage);
            //this.tracingService.Trace(TracingItemType.PostImage, EntityTraceHelper.TraceAttributes(postEntityImage));
            //subgrid_ratedescriptordetail
            //crmp_contract_crmp_ratedescriptorsetdetail_Contract
            //crmp_policy for policy   crmp_contract for plan
            //crmp_ratedescriptorsetdetail for rdd

            List<Entity> results = GetRelatedEntities(service, "crmp_contract", entity.Id, "crmp_contract_crmp_ratedescriptorsetdetail_Contract", 
                "crmp_ratedescriptorsetdetail").ToList();

            decimal total = 0.000M;
            this.tracingService.Trace("About to calculate total:");
            foreach(Entity e in results)
            {
                total += Convert.ToDecimal(e["new_totalmonthlytext"]);
                Console.WriteLine(e["new_totalmonthlytext"]);
                this.tracingService.Trace(e["new_totalmonthlytext"].ToString());
            }
            this.tracingService.Trace("Total finished.");
            try
            {
                //total = total / 0;
                //entity.Attributes.Add("new_totalmonthlycostthree", total);
                this.tracingService.Trace("About to set total.");
                //entity["new_totalmonthlycostthree"] = total;
                entity.Attributes["new_totalmonthlycostthree"] = total;
                this.tracingService.Trace("Total: ", entity["new_totalmonthlycostthree"].ToString());
                this.tracingService.Trace("Total set. Abut to update.");
                this.tracingService.Trace("Entity: ", entity);
                //service.Update(entity);
                this.tracingService.Trace("Updated. About to handle success");
                this.tracingService.HandleSuccess();
                this.tracingService.Trace("Success Handled!");
            }
            catch (Exception ex)
            {
                this.tracingService.HandleException(ex);
                throw new InvalidPluginExecutionException(ex.Message + " - Something went wrong.");
            }
        }
    }
}
}

【问题讨论】:

    标签: c# plugins dynamics-crm


    【解决方案1】:

    经过一番谷歌搜索后发现了问题。我补充说:

    if (context.Depth > 1) { return; }
    

    在上下文被实例化之后。在取消注释 service.Update(entity); 之后,它就像一个魅力。

    【讨论】:

      【解决方案2】:

      您必须小心 Context.Deph 验证。

      使用 Depth 属性时必须小心,因为可能会遇到更复杂的情况。例如,数据导入可能会触发工作流来更新成员的“全名”,这反过来将执行我们的插件。在这种情况下,插件第一次执行时深度将为 3。如果你保持上面的代码 sn-p 不变,插件逻辑将永远不会被执行。 -->http://roscode.wordpress.com/2013/04/24/crm-2011-plugins-avoiding-infinite-loops/

      其他解决方案是:

      1. 不要使用目标实体进行更新。在代码中构建一个新的实体对象,只填写您需要的字段并过滤将触发插件注册工具更新的属性。

      2. 在 Pre-Step 中注册您的插件并将要更新的属性直接写入目标。无需更新。

      【讨论】:

        猜你喜欢
        • 1970-01-01
        • 1970-01-01
        • 1970-01-01
        • 2013-03-16
        • 2014-01-09
        • 2014-08-06
        • 1970-01-01
        • 2023-03-04
        • 1970-01-01
        相关资源
        最近更新 更多