我不知道更新最大值后如何获取最大金额。
当我更新最高金额时,最低金额不会更新为新的最低金额25,000.01
if (context.MessageName == "Create") {
Guid RebateLevelsId = new Guid();
RebateLevelsId = targetEntity.Id;
if (targetEntity.Attributes.Contains("new_usagerebate")) {
EntityReference usageRebateEnt = (EntityReference) targetEntity.Attributes["new_usagerebate"];
Guid usageRebateId = usageRebateEnt.Id;
EntityCollection rebateLevelEnt = GetEntityCollectionRebateLevel(service, "new_rebatelevels", "new_usagerebate", usageRebateId, new ColumnSet(true));
Entity rebateLevelEntity = new Entity("new_rebatelevels", RebateLevelsId);
attributes A = new attributes();
if (rebateLevelEnt.Entities.Count > 0) {
for (int i = 0; i < rebateLevelEnt.Entities.Count; i++) {
if (i == rebateLevelEnt.Entities.Count - 1) {
A.level = i + 1;
}
if (i == rebateLevelEnt.Entities.Count - 2) {
A.Max_Amount = rebateLevelEnt.Entities[i].GetAttributeValue < decimal > ("new_maxamount");
}
}
rebateLevelEntity["new_level"] = A.level.ToString();
rebateLevelEntity["new_minamount"] = A.Max_Amount + 0.01 m;
service.Update(rebateLevelEntity);
} else {
rebateLevelEntity["new_level"] = 1. ToString();
service.Update(rebateLevelEntity);
}
}
}
答案 0 :(得分:2)
我对这个问题进行了思考,并编写了一个示例说明如何处理该问题。
我一直在寻找一种健壮的解决方案,该解决方案可以同时调整我们正在创建或更新的层次之上和之下的水平。此解决方案涵盖的案例包括:
缺少的一件事是确保用户不跳过级别的逻辑。另一个是处理删除操作。
我没有在D365系统中创建实体,而是将其构建为在控制台应用程序中与虚拟数据一起运行,并且IOrganizationService
调用已注释掉。但是,它使用EntityCollection
和Entity
类,因此您应该能够轻松地插入实时数据。
我采用了一种面向对象的方法。 Level
类最初是作为包装器来公开new_rebatelevel's
数据的,而不必不断使用GetAttributeValue<>
。它成长为一个健壮的类,承担着很大的负担。
target
代表已创建或更新的级别。
主要内容:
class Program
{
static void Main(string[] args)
{
var app = new App_CalcMinMax();
app.Run();
if (System.Diagnostics.Debugger.IsAttached)
{
Console.WriteLine("\nPress <Enter> to continue...");
Console.ReadLine();
}
}
}
和“应用”:
using Microsoft.Xrm.Sdk;
using System;
using System.Collections.Generic;
using System.Linq;
using System.Text;
class App_CalcMinMax
{
public void Run()
{
var rebates = new UsageRebate(toCollection(new List<Entity>())); //start with an empty list
//process various level create and update events
//and display the results of each event
//.Process() takes the level #, the min, and the max
rebates.Process(1, 0, 10000);
rebates.Process(2, 11000.01m, 20000);
rebates.Process(3, 21000.01m, 30000);
rebates.Process(1, 0, 9000);
rebates.Process(2, 10000, 15000);
rebates.Process(3, 17000, 35000);
rebates.Process(3, 12000, 24000);
rebates.Process(2, 8000, 20000);
rebates.Process(1, 0, 25000);
rebates.Process(2, 14000, 19000);
}
private class Level
{
private Entity e;
private Level lower;
private Level upper;
public int Num => e.GetAttributeValue<int>("new_level");
public decimal Min => e.GetAttributeValue<Money>("new_minamount").Value;
public decimal Max => e.GetAttributeValue<Money>("new_maxamount").Value;
public bool IsValidLower => lower == null ? true : Min > lower.Min;
public bool IsValidUpper => upper == null ? true : Max < upper.Max;
public bool IsValid => IsValidLower && IsValidUpper;
public bool AdjustLower => lower == null ? false : Min - 0.01m != lower.Max;
public bool AdjustUpper => upper == null ? false : Max + 0.01m != upper.Min;
public Level(Entity e)
{
this.e = e;
}
public void ValidateLower(Level lower)
{
this.lower = lower;
}
public void ValidateUpper(Level upper)
{
this.upper = upper;
}
public void SetMin(decimal value, IOrganizationService service = null)
{
e["new_minamount"] = new Money(value);
//service.Update(e);
}
public void SetMax(decimal value, IOrganizationService service = null)
{
e["new_maxamount"] = new Money(value);
//service.Update(e)
}
public override string ToString()
{
return $" Level: {Num}\tmin: { Min.ToString("N2"),9}\tmax: { Max.ToString("N2"),9}";
}
}
private class UsageRebate
{
private IOrganizationService service;
private EntityCollection ec;
private IEnumerable<int> levelNums => Levels.Select(l => l.Num);
public IEnumerable<Entity> Entities => ec.Entities;
public IEnumerable<Level> Levels => Entities.Select(e => new Level(e));
public UsageRebate(EntityCollection ec, IOrganizationService service = null)
{
this.ec = ec;
this.service = service;
}
public void Process(int num, decimal min, decimal max)
{
var target = toEntity(num, min, max);
var level = new Level(target);
Level prior = null;
Level next = null;
Console.WriteLine($"Target: {level.ToString()}");
if (tryGetLevel(level.Num-1,out prior))
{
level.ValidateLower(prior);
}
if (tryGetLevel(level.Num + 1, out next))
{
level.ValidateUpper(next);
}
if (level.IsValid)
{
if (exists(level.Num))
{
update(target);
}
else
{
add(target);
}
if (level.AdjustLower)
{
prior.SetMax(level.Min - 0.01m);
}
if (level.AdjustUpper)
{
next.SetMin(level.Max + 0.01m);
}
}
else
{
string message = "Exception: ";
if (!level.IsValidLower)
{
message += $"Level {level.Num} Min is less than Level {prior.Num} Min\n";
}
if (!level.IsValidUpper)
{
message += $"Level {level.Num} Max exceeds Level {next.Num} Max";
}
Console.WriteLine(message);
//throw new Exception(message);
}
Console.WriteLine($"Results:\n{ToString()}");
}
private bool tryGetLevel(int num, out Level level)
{
var ex = exists(num);
level = ex ? get(num) : null;
return ex;
}
private void add(Entity entity)
{
ec.Entities.Add(entity);
//service.Create(entity);
}
private void update(Entity entity)
{
var e = get(entity);
e["new_minamount"] = entity["new_minamount"];
e["new_maxamount"] = entity["new_maxamount"];
//service.Update(entity);
}
private bool exists(int num)
{
return levelNums.Contains(num);
}
private Level get(int num)
{
return Levels.Where(l => l.Num == num).Single();
}
private Entity get(Entity entity)
{
return Entities.Where(e => new Level(e).Num == new Level(entity).Num).Single();
}
private Entity toEntity(int level, decimal min, decimal max)
{
return new Entity
{
LogicalName = "new_rebatelevel",
Id = Guid.NewGuid(),
Attributes =
{
new KeyValuePair<string, object>("new_level", level),
new KeyValuePair<string, object>("new_minamount", new Money(min)),
new KeyValuePair<string, object>("new_maxamount", new Money(max))
}
};
}
public override string ToString()
{
var sb = new StringBuilder();
Levels.ToList().ForEach(l => sb.AppendLine(l.ToString()));
return sb.ToString();
}
}
private EntityCollection toCollection(List<Entity> list)
{
var ec = new EntityCollection();
ec.EntityName = "new_rebatelevel";
ec.Entities.AddRange(list);
return ec;
}
}
输出:
目标:级别:1分钟:0.00最大值:10,000.00
结果:
级别:1分钟:0.00最大值:10,000.00
目标:级别:2分钟:11,000.01最大:20,000.00
结果:
级别:1分钟:0.00最大:11,000.00
级别:2分钟:11,000.01最大:20,000.00
目标:等级:3分钟:21,000.01最高:30,000.00
结果:
级别:1分钟:0.00最大:11,000.00
等级:2分钟:11,000.01最大:21,000.00
级别:3分钟:21,000.01最大值:30,000.00
目标:等级:1分钟:0.00最高:9,000.00
结果:
级别:1分钟:0.00最大:9,000.00
等级:2分钟:9,000.01最大:21,000.00
级别:3分钟:21,000.01最大值:30,000.00
目标:等级:2分钟:10,000.00最大值:15,000.00
结果:
等级:1分钟:0.00最大:9,999.99
级别:2分钟:10,000.00最大:15,000.00
水平:3分钟:15,000.01最大:30,000.00
目标:等级:3分钟:17,000.00最大值:35,000.00
结果:
等级:1分钟:0.00最大:9,999.99
级别:2分钟:10,000.00最大:16,999.99
级别:3分钟:17,000.00最大:35,000.00
目标:等级:3分钟:12,000.00最大值:24,000.00
结果:
等级:1分钟:0.00最大:9,999.99
级别:2分钟:10,000.00最大:11,999.99
级别:3分钟:12,000.00最大:24,000.00
目标:等级:2分钟:8,000.00最大值:20,000.00
结果:
等级:1分钟:0.00最大:7,999.99
级别:2分钟:8,000.00最大:20,000.00
级别:3分钟:20,000.01最大值:24,000.00
目标:等级:1分钟:0.00最高:25,000.00
例外:1级最大超出2级最大
结果:
等级:1分钟:0.00最大:7,999.99
级别:2分钟:8,000.00最大:20,000.00
级别:3分钟:20,000.01最大值:24,000.00
目标:等级:2分钟:14,000.00最大值:19,000.00
结果:
等级:1分钟:0.00最大:13,999.99
级别:2分钟:14,000.00最大:19,000.00
级别:3分钟:19,000.01最大:24,000.00
按Enter继续...