我需要足够的帮助才能提供帮助!我正在运行Dynamics 365的实例,我需要确定是否使用FetchXML,LINQ查询或查询表达式来查询我称为合同行的实体的帮助。...
让我解释一下该项目:
在合同实体内部,我的合同行如下所示:
合同行(加总)将告诉您在整个合同期内每周的每一天订购什么(以及订购多少)。合同的期限可能超过6个月。.我要做的是获取此信息并将其扩展。所以我想获得从合同开始到合同结束的每一天的订单情况。创建合同后,将在另一个称为“单位订单”的实体中创建一条记录,如下所示:
在单元订单实体内部,存在另一个实体的子网格(称为alter unit order实体)。该实体与单元订单实体具有1:N的关系。就像来自合同实体的数据进入单元订单实体一样,我们希望来自合同行实体的数据进入变更单元订单实体。这里的技巧是编写一种算法,该算法处理合同行中的数据到更改单位订单实体中。我们总结了在合同的每一天为AM SNACK,午餐和PM SNACK订购了多少。请注意,订单仅在工作日完成(周末没有订单)。我已经开始编写插件,并且已经设法从合同实体中查询合同行子网格。我的问题是,我坚持这一点,我需要帮助来整理算法以吐出我想要的东西……这是我到目前为止所拥有的:
using System;
using System.ServiceModel;
using Microsoft.Xrm.Sdk;
using Microsoft.Xrm.Sdk.Client;
using Microsoft.Xrm.Sdk.Query;
/// <summary>
/// This plugin takes the data provided in the contract lines and makes Unit Orders.. Inside the unit orders, an Alter Unit Orders table is present.
/// The Alter Unit Orders table describes the daily order for each day in the contract's duration.
/// </summary>
namespace DCWIMS.Plugins
{
[CrmPluginRegistration(MessageNameEnum.Update,
"contract",
StageEnum.PreOperation,
ExecutionModeEnum.Synchronous,
"title",
"Post-Update Contract",
1000,
IsolationModeEnum.Sandbox,
Image1Name = "PreImage",
Image1Type = ImageTypeEnum.PreImage,
Image1Attributes = "title")]
public class UnitPlugin : IPlugin
{
public void Execute(IServiceProvider serviceProvider)
{
// Extract the tracing service for use in debugging sandboxed plug-ins.
// Wil be registering this plugin, thus will need to add tracing service related code.
ITracingService tracing = (ITracingService)serviceProvider.GetService(typeof(ITracingService));
//obtain execution context from service provider.
IPluginExecutionContext context = (IPluginExecutionContext)
serviceProvider.GetService(typeof(IPluginExecutionContext));
// The InputParameters colletion contains all the data passed in the message request.
if (context.InputParameters.Contains("Target") &&
context.InputParameters["Target"] is Entity)
{
//obtain the target entity from the input parameters.
Entity entity = (Entity)context.InputParameters["Target"];
//verify that the target entity represents the the contract entity and is in an active state
if (entity.LogicalName != "contract" && entity.GetAttributeValue<OptionSetValue>("statecode").Value != 0)
return;
//obtain the organization service for web service calls.
IOrganizationServiceFactory serviceFactory =
(IOrganizationServiceFactory)serviceProvider.GetService(typeof(IOrganizationServiceFactory));
IOrganizationService service = serviceFactory.CreateOrganizationService(context.UserId);
try
{
//Get Contract StartDate
DateTime startDate = (DateTime)entity["activeon"];
//Get Contract EndDate
DateTime endDate = (DateTime)entity["expireson"];
//Get all weekdays in the contract duration
Eachday range = new Eachday();
var weekdays = range.WeekDay(startDate, endDate); //weekdays list
//Get Contract Number
string contractNumber = (string)entity["contractnumber"];
//Query and aggregate each Weekday's order for the 3 different meal times...
//AM SNACK
//LUNCH
//PM SNACK
var am_list = new List<int>();
var lunch_list = new List<int>();
var pm_list = new List<int>();
foreach(var day in weekdays)
{
var alterunit = new Entity("new_alterunitorder");
alterunit.Attributes.Add("new_orderdate", DateTime.Parse(day));
switch (day.Split(',')[0])
{
case "Monday":
alterunit.Attributes.Add("new_amsnack", am_list[0]);
alterunit.Attributes.Add("new_lunch", lunch_list[0]);
alterunit.Attributes.Add("new_pmsnack", pm_list[0]);
break;
case "Tuesday":
alterunit.Attributes.Add("new_amsnack", am_list[1]);
alterunit.Attributes.Add("new_lunch", lunch_list[1]);
alterunit.Attributes.Add("new_pmsnack", pm_list[1]);
break;
case "Wednesday":
alterunit.Attributes.Add("new_amsnack", am_list[2]);
alterunit.Attributes.Add("new_lunch", lunch_list[2]);
alterunit.Attributes.Add("new_pmsnack", pm_list[2]);
break;
case "Thursday":
alterunit.Attributes.Add("new_amsnack", am_list[3]);
alterunit.Attributes.Add("new_lunch", lunch_list[3]);
alterunit.Attributes.Add("new_pmsnack", pm_list[3]);
break;
case "Friday":
alterunit.Attributes.Add("new_amsnack", am_list[4]);
alterunit.Attributes.Add("new_lunch", lunch_list[4]);
alterunit.Attributes.Add("new_pmsnack", pm_list[4]);
break;
default:
Console.WriteLine($"An unexpected value ({day.Split(',')})");
break;
}
alterunit.Attributes.Add("new_name", contractNumber);
service.Create(alterunit);
}
}
catch (FaultException<OrganizationServiceFault> ex)
{
throw new InvalidPluginExecutionException("An error occured.. Phil is responsible.", ex);
}
catch (Exception ex)
{
tracing.Trace("An Error Occured: {0}", ex.ToString());
throw;
}
}
}
}
}
这是我用来在合同期限内获取所有工作日的代码:
public class Eachday
{
public List<string> WeekDay(DateTime from, DateTime thru)
{
List<string> days_list = new List<string>();
for (var day = from.Date; day.Date <= thru.Date; day = day.AddDays(1))
{
days_list.Add(day.ToLongDateString());
if (day.DayOfWeek == DayOfWeek.Sunday || day.DayOfWeek == DayOfWeek.Saturday)
days_list.Remove(day.ToShortDateString());
}
return days_list;
}
我在try块中添加了此代码,以获取工作日列表:
//Get Contract StartDate
DateTime startDate = (DateTime)entity["activeon"];
//Get Contract EndDate
DateTime endDate = (DateTime)entity["expireson"];
//Get all weekdays in the contract duration
Eachday range = new Eachday();
var weekdays = range.WeekDay(startDate, endDate);
我需要将每周的每周订购数量放入清单中。本质上,我将有3个列表。然后我将使用列表中的开关吐出总数!
foreach(var day in weekdays)
{
var alterunit = new Entity("new_alterunitorder");
alterunit.Attributes.Add("new_orderdate", DateTime.Parse(day));
switch (day.Split(',')[0])
{
case "Monday":
alterunit.Attributes.Add("new_amsnack", am_list[0]);
alterunit.Attributes.Add("new_lunch", lunch_list[0]);
alterunit.Attributes.Add("new_pmsnack", pm_list[0]);
break;
case "Tuesday":
alterunit.Attributes.Add("new_amsnack", am_list[1]);
alterunit.Attributes.Add("new_lunch", lunch_list[1]);
alterunit.Attributes.Add("new_pmsnack", pm_list[1]);
break;
case "Wednesday":
alterunit.Attributes.Add("new_amsnack", am_list[2]);
alterunit.Attributes.Add("new_lunch", lunch_list[2]);
alterunit.Attributes.Add("new_pmsnack", pm_list[2]);
break;
case "Thursday":
alterunit.Attributes.Add("new_amsnack", am_list[3]);
alterunit.Attributes.Add("new_lunch", lunch_list[3]);
alterunit.Attributes.Add("new_pmsnack", pm_list[3]);
break;
case "Friday":
alterunit.Attributes.Add("new_amsnack", am_list[4]);
alterunit.Attributes.Add("new_lunch", lunch_list[4]);
alterunit.Attributes.Add("new_pmsnack", pm_list[4]);
break;
default:
Console.WriteLine($"An unexpected value ({day.Split(',')})");
break;
}
alterunit.Attributes.Add("new_name", contractNumber);
service.Create(alterunit);
}
答案 0 :(得分:1)
我看到您是首次使用插件。我发现QueryExpression
通常非常复杂。相反,您应该使用fetchXml
。简而言之,fetchXml
是Dynamics中查询的语言。所有视图都使用它。您可以在高级查找窗口中生成fetchXml。
就性能而言,它也是最好的。据我所知,在插件中没有其他选择可以计算总和而不检索内存中的全部数据。
这是我在MSDN中找到的一个例子
string estimatedvalue_sum = @" <fetch distinct='false' mapping='logical' aggregate='true'>
<entity name='opportunity'>
<attribute name='estimatedvalue' alias='estimatedvalue_sum' aggregate='sum' />
</entity> </fetch>";
EntityCollection estimatedvalue_sum_result =
_serviceProxy.RetrieveMultiple(new FetchExpression(estimatedvalue_sum));
foreach (var c in estimatedvalue_sum_result.Entities) {
decimal aggregate7 = ((Money)((AliasedValue)c["estimatedvalue_sum"]).Value).Value;
System.Console.WriteLine("Sum of estimated value of all opportunities: " + aggregate7);
}
来源:https://msdn.microsoft.com/en-us/library/gg309565.aspx#sum
此外,这是一些一般性提示:
_serviceProxy
是服务变量第一次修订: 您可以创建一个包含每天总金额的实体。用正确的类型替换“(金钱)”。不确定是货币还是整数。
foreach(var unit in unitsum_am_result.Entities)
{
decimal mondaySum = ((Money)((AliasedValue)unit["new_mondayunits_amsum"]).Value).Value;
decimal tuesdaySum = ((Money)((AliasedValue)unit["new_tuesdayunits_amsum"]).Value).Value;
decimal wednesdaySum = ((Money)((AliasedValue)unit["new_unitswednesday_amsum"]).Value).Value;
decimal thursdaySum = ((Money) ((AliasedValue)unit["new_unitsthursday_amsum"]).Value).Value;
decimal fridaySum = ((Money) ((AliasedValue)unit["new_unitsfriday_amsum"]).Value).Value;
var unitOrder = new Entity("new_unit_order");
unitOrder.Attributes.Add("new_orderSum", mondaySum);
unitOrder.Attributes.Add("new_date", mondayDate);
_serviceProxy.Create(unitOrder);
// Do the same for the other sums/days
}
第二次修订 为了从合同中获得查找值,最好的选择是使用插件注册工具在插件上创建原像。在图像中,选择您需要从实体中检索的字段。它像目标一样工作。
PluginExecutionContext.PreEntityImages != null && PluginExecutionContext.PreEntityImages.Count >= 1 ? PluginExecutionContext.PreEntityImages.FirstOrDefault().Value : null;
请注意,如果在更新事件中未修改单位,则将在图像中找到该值。如果确实要更新单位,则会在图像中找到旧值,而在目标中找到新值。因此,您始终必须同时检查两者。