Skip to main content
 首页 » 编程设计

c#之Dynamics 365 CRM Online之使用不在集合中的字段(尚未更新)

2024年02月04日28over140

总体问题是:如何在 D365 CRM 的插件中访问不在我的集合中(尚未更新)的实体变量?

我已经为此纠结了很长一段时间,现在,我向论坛大神们求助,以帮助理解这里发生的事情。

我在 D365 CRM (v9.0) 中对工单实体进行了自定义。本质上,无论何时更新三个字段中的一个,我每次都需要执行相同的逻辑。无论出于何种原因,该插件仅在所有三个字段都在一次操作中更新时才能工作。如果我只更新一个,我将收到“字典中不存在键”错误,表示我的变量不在当前集合中。

我试图将我的“包含”检查更改为包含 XYZ ||包含 ABC ||包含 123,但立即失败。然后,我尝试将每个条件相互嵌套,但当然,最低的嵌套不会被触及。然后我尝试取消嵌套,然后单独尝试每个“包含”检查,然后继续执行所有三个 if block 中的逻辑。到目前为止,所有这些都让我失望了。

我在这里遗漏了什么吗?出于测试目的,我将其设置为触发所有属性(不仅仅是我想检查的三个属性),但即使这样对我来说也失败了。我还与一位在 CRM 开发方面经验比我丰富得多的同事交谈过,你可以在“FieldValue”函数调用中看到一些工件(尽管我已经去掉了 FieldValue从此代码片段中运行)。

我是 CRM 开发的新手,但从 4.0 开始就开始使用 MSCRM。
非常感谢任何建议。

总体问题是:如何在 D365 CRM 的插件中访问不在我的集合中(尚未更新)的实体变量?

下面的代码,删除了对我客户姓名的引用:

using System; 
using System.Linq; 
using System.Collections.Generic; 
using Microsoft.Xrm.Sdk; 
using Microsoft.Xrm.Sdk.Client; 
using Microsoft.Xrm.Sdk.Query; 
using Microsoft.Crm.Sdk.Messages; 
using System.ServiceModel; 
using System.Data.SqlClient; 
using System.Threading.Tasks; 
 
namespace ClientNTE 
{ 
    public class NTEExceedance : IPlugin 
    { 
        public void Execute(IServiceProvider serviceProvider) 
        { 
            IPluginExecutionContext context = (IPluginExecutionContext)serviceProvider.GetService(typeof(IPluginExecutionContext)); 
            IOrganizationServiceFactory factory = (IOrganizationServiceFactory)serviceProvider.GetService(typeof(IOrganizationServiceFactory)); 
            IOrganizationService service = factory.CreateOrganizationService(context.UserId); 
            //Extract the tracing service for use in debugging sandboxed plug-ins. 
            ITracingService tracingService = (ITracingService)serviceProvider.GetService(typeof(ITracingService)); 
 
            Money subtotal = null; 
            Money nte = null; 
            Decimal nte_percent = 0; 
 
            Decimal subtotalDecimal = 0; 
            Decimal nteDecimal = 0; 
            Decimal amountDiffDecimal = 0; 
            Decimal percentDifference = 0; 
 
            try 
            { 
 
                if (context.InputParameters.Contains("Target") && context.InputParameters["Target"] is Entity) 
                { 
                    Entity entity = (Entity)context.InputParameters["Target"]; 
                    if (entity.LogicalName == "msdyn_workorder") 
                    { 
                        //code fires onChange of NTE Amount (same logic will apply to NTE % and Est Subtotal Amount) 
                        if (entity.Attributes.Contains("CLIENT_nteamount") == true) 
                        { 
 
 
                            //trying to use the FieldValue function to grab these fields into collection, commented out for now 
                            //String NewValue = FieldValue(service, new Guid(entity["msdyn_workorderid"].ToString())); 
                            //String NewSubTotal = FieldValue(service, new Guid(entity["msdyn_workorderid"].ToString()), entity["msdyn_estimatesubtotalamount"].ToString()); 
                            //String NewNTE = FieldValue(service, new Guid(entity["msdyn_workorderid"].ToString()), entity["CLIENT_nteamount"].ToString()); 
                            //String Newpercent = FieldValue(service, new Guid(entity["msdyn_workorderid"].ToString()), entity["CLIENT_ntepercent"].ToString()); 
 
                            subtotal = (Money)entity.Attributes["msdyn_estimatesubtotalamount"]; 
                            nte = (Money)entity.Attributes["CLIENT_nteamount"]; 
                            nte_percent = (Decimal)entity.Attributes["CLIENT_ntepercent"]; 
 
 
 
                            subtotalDecimal = subtotal.Value; 
                            nteDecimal = nte.Value; 
 
                            amountDiffDecimal = (subtotalDecimal - nteDecimal); 
                            percentDifference = ((amountDiffDecimal / nteDecimal) * 100); 
 
                            // decimal percentDifference = 100; 
                            //decimal nte_percent = 50; 
                            if (percentDifference > nte_percent) 
                            { 
                                //know this snippet works 
                                entity["CLIENT_nteexceeded"] = true; 
                            } 
                            if (percentDifference <= nte_percent) 
                            { 
                                //know this snippet works 
                                entity["CLIENT_nteexceeded"] = false; 
                            } 
                        } 
                        if (entity.Attributes.Contains("CLIENT_ntepercent") == true) 
                        { 
                            subtotal = (Money)entity.Attributes["msdyn_estimatesubtotalamount"]; 
                            nte = (Money)entity.Attributes["CLIENT_nteamount"]; 
                            nte_percent = (Decimal)entity.Attributes["CLIENT_ntepercent"]; 
 
 
                            subtotalDecimal = subtotal.Value; 
                            nteDecimal = nte.Value; 
 
                            amountDiffDecimal = (subtotalDecimal - nteDecimal); 
                            percentDifference = ((amountDiffDecimal / nteDecimal) * 100); 
 
                            // decimal percentDifference = 100; 
                            //decimal nte_percent = 50; 
                            if (percentDifference > nte_percent) 
                            { 
                                //know this snippet works 
                                entity["CLIENT_nteexceeded"] = true; 
                            } 
                            if (percentDifference <= nte_percent) 
                            { 
                                //know this snippet works 
                                entity["CLIENT_nteexceeded"] = false; 
                            } 
                        } 
                        if (entity.Attributes.Contains("msdyn_estimatesubtotalamount") == true) 
                        { 
 
 
                            subtotal = (Money)entity.Attributes["msdyn_estimatesubtotalamount"]; 
                            nte = (Money)entity.Attributes["CLIENT_nteamount"]; 
                            nte_percent = (Decimal)entity.Attributes["CLIENT_ntepercent"]; 
 
 
                            subtotalDecimal = subtotal.Value; 
                            nteDecimal = nte.Value; 
 
                            amountDiffDecimal = (subtotalDecimal - nteDecimal); 
                            percentDifference = ((amountDiffDecimal / nteDecimal) * 100); 
 
                            // decimal percentDifference = 100; 
                            //decimal nte_percent = 50; 
                            if (percentDifference > nte_percent) 
                            { 
                                //know this snippet works 
                                entity["CLIENT_nteexceeded"] = true; 
                            } 
                            if (percentDifference <= nte_percent) 
                            { 
                                //know this snippet works 
                                entity["CLIENT_nteexceeded"] = false; 
                            } 
 
 
                            /* 
                            Money m = (Money)entity.Attributes["new_evalmoneyvalue"]; 
 
                            decimal actualAmount = m.Value; 
 
                            entity["new_evaldecimal"] = actualAmount; 
 
                            entity["new_evalmoneyvalue"] = new Money((decimal)actualAmount * 2); 
                            */ 
                        } 
 
                    } 
                } 
 
 
 
            } 
            catch (FaultException<OrganizationServiceFault> e) 
            { 
                tracingService.Trace("CLIENTPlugin - Update NTEExceededNonCalc: {0}", e.ToString()); 
                throw e; 
            } 
        } 
 
    } 
 
} 

请您参考如下方法:

How do I access entity variables that are not in my collection (haven't been updated) in a plugin for D365 CRM?

答案:图像(前图像或后图像)

在Update步骤注册一个带有必要属性的Image,这样你会得到整个实体对象或者你标记的每一个属性。基本上它是一个高效的平台检索调用,并在 Context 本身中为您服务。

例如,在您的情况下,使用 PreImage(所有 3 个属性)注册更新后步骤。因此修改后的属性将在 (Entity)context.InputParameters["Target"] 中。可以从 (Entity)context.PreEntityImages["Image"] 使用未修改的属性。 Read more

Also Contains 可能总是如此,因此请检查 Money/Decimal 字段,如解释的 here .

Money myMoneyField = (Money)EntityObject.GetAttributeValue<Money>(Amount); 
 
decimal actualAmount; 
 
if (myMoneyField != null) 
{ 
    actualAmount = myMoneyField.Value; 
} 

现在您拥有交易前后的属性值,因此您决定并存储要在计算中使用的值。

Entity orderEntity = (Entity)context.InputParameters["Target"]; 
Entity preOrderEntity = (Entity)context.PreEntityImages["Image"]; 
Decimal preNTEamount = preOrderEntity.GetAttributeValue<Money>("CLIENT_nteamount") != null ? ((Money)preOrderEntity.GetAttributeValue<Money>("CLIENT_nteamount")).Value : 0; 
Decimal newNTEamount = orderEntity.GetAttributeValue<Money>("CLIENT_nteamount") != null ? ((Money)orderEntity.GetAttributeValue<Money>("CLIENT_nteamount")).Value : preNTEamount;