Dynamics 365 CRM Online - 使用不在集合中的字段(尚未更新)
Dynamics 365 CRM Online - Use a Field that is NOT in collection (Hasn't been updated)
总体问题是:如何在 D365 CRM 的插件中访问不在我的集合中(尚未更新)的实体变量?
我已经为此纠结了很长一段时间,现在,我向论坛大神们求助,以了解这里发生的事情。
我在 D365 CRM (v9.0) 中对工单实体进行了自定义。本质上,无论何时更新三个字段中的一个,我每次都需要执行相同的逻辑。无论出于何种原因,该插件仅在所有三个字段都在一次操作中更新时才能工作。如果我只更新一个,我会收到 "key not present in dictionary" 错误,表示我的变量不在当前集合中。
我试图将我的 "contains" 检查更改为包含 XYZ ||包含 ABC ||包含 123,但立即失败。然后,我尝试将每个条件相互嵌套,但当然,最低的嵌套不会被触及。然后我尝试取消嵌套,然后单独尝试每个 "contains" 检查,然后继续执行所有三个 if 块中的逻辑。所有这一切都让我失望了。
这里有我遗漏的东西吗?出于测试目的,我将其设置为触发所有属性(不仅仅是我想检查的三个属性),但即使这样对我来说也失败了。我还与一位在 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?
答案:图片(预图片或Post-图片)
在Update步骤注册一个带有必要属性的Image,这样你会得到整个实体对象或者你标记的每一个属性。基本上它是一个高效的平台检索调用,并在上下文中为您服务。
例如,在您的情况下,使用 PreImage(所有 3 个属性)注册 Post-更新步骤。所以修改后的属性会在(Entity)context.InputParameters["Target"]
中。可以从 (Entity)context.PreEntityImages["Image"]
使用未修改的属性。 Read more
Also Contains 可能总是如此,因此请检查 Money/Decimal 字段,如 所述。
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;
总体问题是:如何在 D365 CRM 的插件中访问不在我的集合中(尚未更新)的实体变量?
我已经为此纠结了很长一段时间,现在,我向论坛大神们求助,以了解这里发生的事情。
我在 D365 CRM (v9.0) 中对工单实体进行了自定义。本质上,无论何时更新三个字段中的一个,我每次都需要执行相同的逻辑。无论出于何种原因,该插件仅在所有三个字段都在一次操作中更新时才能工作。如果我只更新一个,我会收到 "key not present in dictionary" 错误,表示我的变量不在当前集合中。
我试图将我的 "contains" 检查更改为包含 XYZ ||包含 ABC ||包含 123,但立即失败。然后,我尝试将每个条件相互嵌套,但当然,最低的嵌套不会被触及。然后我尝试取消嵌套,然后单独尝试每个 "contains" 检查,然后继续执行所有三个 if 块中的逻辑。所有这一切都让我失望了。
这里有我遗漏的东西吗?出于测试目的,我将其设置为触发所有属性(不仅仅是我想检查的三个属性),但即使这样对我来说也失败了。我还与一位在 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?
答案:图片(预图片或Post-图片)
在Update步骤注册一个带有必要属性的Image,这样你会得到整个实体对象或者你标记的每一个属性。基本上它是一个高效的平台检索调用,并在上下文中为您服务。
例如,在您的情况下,使用 PreImage(所有 3 个属性)注册 Post-更新步骤。所以修改后的属性会在(Entity)context.InputParameters["Target"]
中。可以从 (Entity)context.PreEntityImages["Image"]
使用未修改的属性。 Read more
Also Contains 可能总是如此,因此请检查 Money/Decimal 字段,如
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;