Dynamics 365 CRM Online - Use a Field that is NOT in collection (Hasn't been updated)

我的未来我决定 提交于 2020-01-24 20:53:45

问题


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

I have been wrestling with this for quite a while, and now, I turn to you, the forum Gods, for help in understanding what's happening here.

I have customizations on the Work Order entity within D365 CRM (v9.0). Essentially, whenever one of three fields is updated, I need to perform the same logic each time. For whatever reason, the plugin will ONLY work when all three fields are updated in a single operation. If I just update one, I will get the "key not present in dictionary" error, signifying that my variable is not in the current collection.

I have tried to alter my "contains" check to be contains XYZ || contains ABC || contains 123, but that fails instantly. Then, I tried to nest each of those conditions within each other, but of course, the lowest nests don't get touched. Then I tried to un-nest, and just try each of the "contains" checks individually, and go ahead and do the logic in all three if blocks. All of this has failed me to this point.

Is there something I am missing here? For testing purposes, I have it set to fire on All Attributes (not just the three that i want to check on), but even that fails for me. I also spoke with a colleague who has quite a bit more experience than I do in the development side of the house for CRM, and you can see some of the artifacts there in the "FieldValue" function calls (though I have stripped out the FieldValue function from this code snip).

I am new-ish to CRM development, but have been working in MSCRM since 4.0.
Any advice is greatly appreciated.

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

Code below, with references to my client's names removed:

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;
            }
        }

    }

}

回答1:


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

Answer: Images (Pre-Image or Post-Image)

Register an Image with necessary attributes in Update step, so you will get the whole entity object or every single attribute you mark. Basically its an efficient Retrieve call by platform & serve you in Context itself.

For example in your case, register the Post-Update step with PreImage (all 3 attributes). So the modified attribute will be in (Entity)context.InputParameters["Target"]. Unmodified attributes can be consumed from (Entity)context.PreEntityImages["Image"]. Read more

Also Contains may come as true always, so check the Money/Decimal fields like explained here.

Money myMoneyField = (Money)EntityObject.GetAttributeValue<Money>(Amount);

decimal actualAmount;

if (myMoneyField != null)
{
    actualAmount = myMoneyField.Value;
}

Now you have the attribute values before & after the transaction, hence you decide & store the value to use in calculation.

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;


来源:https://stackoverflow.com/questions/50915478/dynamics-365-crm-online-use-a-field-that-is-not-in-collection-hasnt-been-upd

易学教程内所有资源均来自网络或用户发布的内容,如有违反法律规定的内容欢迎反馈
该文章没有解决你所遇到的问题?点击提问,说说你的问题,让更多的人一起探讨吧!