C# 如何编写此LINQ以应用业务逻辑?
我正在尝试应用一些业务逻辑。C# 如何编写此LINQ以应用业务逻辑?,c#,linq,c#-4.0,C#,Linq,C# 4.0,我正在尝试应用一些业务逻辑。 我的问题是关于在以下对象模型上使用LINQ来应用业务逻辑。我已相应地填充了以下对象: public class Waiver { public string Id { get; set; } public int Type { get; set; } public decimal Amount { get; set; } } 要应用的业务逻辑: 1.)申请行项目豁免 如果行项目豁免[类型]为1111,则从单价中扣除行项目豁免金额 如果行项目豁免[
我的问题是关于在以下对象模型上使用LINQ来应用业务逻辑。我已相应地填充了以下对象:
public class Waiver
{
public string Id { get; set; }
public int Type { get; set; }
public decimal Amount { get; set; }
}
要应用的业务逻辑:
1.)申请行项目豁免如果行项目豁免[类型]为1111,则从单价中扣除行项目豁免金额
如果行项目豁免[类型]为2222,则扣除行项目豁免金额作为单价的百分比
如果行项目豁免[类型]为3333,则扣除行项目豁免金额(行价格=数量*单价)
如果行项目豁免[类型]为4444,则扣除行项目豁免金额作为离线价格的百分比 2.)申请订单豁免 如果订单豁免[类型]为4444,则在应用行项目豁免后,从订单总价中扣除订单豁免金额
如果订单豁免[类型]为8888,则在应用行项目豁免后,扣除订单豁免金额作为订单价格的百分比 实现这一目标的最佳方式是什么
GetWaivedPrice(decimal unitPrice, int qty, IEnumerable<Waiver> waiver)
我不认为LINQ有这样的情况。只需依次应用每个
Waver
private decimal GetWaivedPrice(decimal unitPrice, int qty,
IEnumerable<Waiver> waiver)
{
//Pseudo code shown for clarifying intent
decimal waivedLineItemAmount = 0m;
//apply all waivers
foreach (var w in waiver) {
switch (w.Type) {
case 1111:
waivedLineItemAmout += someComputation();
break;
case 2222:
waivedLineItemAmout += someComputation();
break;
case 3333:
waivedLineItemAmout += someComputation();
break;
}
}
return waivedLineItemAmount;
}
私有十进制价格(十进制单价、整数数量、,
(可数弃权)
{
//显示用于澄清意图的伪代码
十进制弃权LineItemAmount=0m;
//适用所有豁免
foreach(弃权中的var w){
开关(w型){
案例1111:
弃权LineItemAmout+=SomeCalculation();
打破
案例2222:
弃权LineItemAmout+=SomeCalculation();
打破
案例3333:
弃权LineItemAmout+=SomeCalculation();
打破
}
}
退还免赔金额;
}
如果您坚持使用LINQ和纯功能风格,那么您可以使用Enumerable.Aggregate来表述这一点,但简单的循环在这里似乎很好。我不认为需要LINQ本身,但可能需要面向对象的设计 相反,我会让弃权处理方法调用中的业务逻辑,比如您现在拥有的
public class Waiver
{
public string Id { get; set; }
public int Type { get; set; }
public decimal Amount { get; set; }
public decimal GetWaivedPrice(decimal unitPrice, int qty) { ... }
}
通过这样做,它将有助于任何未来的linq预测或操作,如此分组,当然,还可以为将来的维护集中业务逻辑
var groupedResult = myWaivers.Select(wv => new
{
Type = wv.Type,
WaivedPrice = wv.GetWaivedPrice( unitPrice, qty)
} )
.GroupBy(wv => wv.Type);
那么:
private static Dictionary<int, Func<decimal, int, Waiver, decimal>> _logic
= new Dictionary<int, Func<decimal, int, Waiver, decimal>>() {
{ 2222, (a, q, w) => a + w.Amount },
{ 3333, (a, q, w) => a + w.Amount },
{ 3333, (a, q, w) => a + w.Amount }
};
private static decimal GetWaivedPrice(decimal unitPrice, int qty,
IEnumerable<Waiver> waiver)
{
return waiver.Aggregate(0m, (a, s) => _logic[s.Type](a, qty, s), a => a);
}
专用静态字典\u逻辑
=新字典(){
{2222,(a,q,w)=>a+w.数量},
{3333,(a,q,w)=>a+w.数量},
{3333,(a,q,w)=>a+w.数量}
};
私有静态十进制价格(十进制单价、整数数量、,
(可数弃权)
{
退货豁免。合计(0米,(a,s)=>_逻辑[s.Type](a,数量,s),a=>a);
}
当然,您必须使用折扣逻辑更新
\u logic
字典,以使其正常工作。业务规则被隔离为单独的关注点(扣除和策略),现在非常简单
// Create a data structure to model the deductions themselves
public class LineItemDeduction
{
public decimal UnitPriceAmount { get; set; }
public decimal UnitPricePercentage { get; set; }
public decimal LinePriceAmount { get; set; }
public decimal LinePricePercentage { get; set; }
// Assumed that waivers are distinct and are not composed together, only applied on the listed price.
public decimal CalculateWaivedPrice(decimal unitPrice, int qty)
{
return ((unitPrice - UnitPriceAmount - (unitPrice * UnitPricePercentage)) * qty) - LinePriceAmount - (unitPrice * qty * LinePricePercentage);
}
}
// Calculate the deductions
private LineItemDeduction CalculateLineItemDeductionStrategy(LineItemDeduction deduction, Waiver waiver)
{
switch (waiver.Type) {
case 1111:
deduction.UnitPriceAmount += waiver.Amount;
break;
case 2222:
deduction.UnitPricePercentage += waiver.Amount;
break;
case 3333:
deduction.LinePriceAmount += waiver.Amount;
break;
case 4444:
deduction.LinePricePercentage += waiver.Amount;
break;
}
return deduction;
}
// Extension method only for LineItem but it's the same principle for order waivers
public static decimal GetWaivedPrice(this IEnumerable<Waiver> waivers, decimal unitPrice, int qty, Func<LineItemDeduction, Waiver, LineItemDeduction> deductionStrategy)
{
return waivers.Aggregate(
new LineItemDeduction(),
deductionStrategy,
d => d.CalculateWaivedPrice(unitPrice, qty)
);
}
// Now to get the waived price
var waivedPrice = waivers.GetWaivedPrice(unitPrice, qty, CalculateLineItemDeductionStrategy);
//创建一个数据结构,对扣减本身进行建模
公共类LineItemDeception
{
公共十进制单位价格金额{get;set;}
公共十进制单位价格百分比{get;set;}
公共十进制LinePriceAmount{get;set;}
公共十进制LinePricePercentage{get;set;}
//假设弃权是不同的,且不是一起组成的,仅适用于上市价格。
公共十进制计算活动价格(十进制单价,整数数量)
{
返回((单价-单价金额-(单价*单价百分比))*数量-行价格金额-(单价*数量*行价格百分比);
}
}
//计算扣除额
专用项目扣除额计算项目扣除额策略(项目扣除额扣除额、豁免豁免)
{
开关(豁免.类型){
案例1111:
扣除.单价金额+=放弃.金额;
打破
案例2222:
扣除额.单价百分比+=放弃额.金额;
打破
案例3333:
扣减额.LinePriceAmount+=放弃额.Amount;
打破
判例4444:
扣除额.LinePricePercentage+=放弃额.Amount;
打破
}
退货扣减;
}
//扩展方法仅适用于行项目,但对于订单豁免也是相同的原则
公共静态十进制GETDPRICE(此IEnumerable弃权、十进制单价、整数数量、函数扣减策略)
{
退货豁免。合计(
新建LineItemDeclusion(),
演绎策略,
d=>d.CalculateAvedPrice(单价、数量)
);
}
//现在要拿到豁免的价格
var弃权价格=弃权。获取弃权价格(单价、数量、计算所得税扣减策略);
您能更具体地说明您有什么问题吗?为什么JSON是对数据执行一些(看似微不足道)操作的问题的一部分?对于这种情况,您对“更好”的定义是什么(可读性、代码大小、行数…)?我的问题是编写GetAguardPrice方法以应用行级豁免的最佳方式。JSON只是输入的一个示例frmat。我已经删除了所有不相关的JSON代码、构造函数和空白-如果需要,请随时改进。请显示您在实现GetAveragedPrice
方面的尝试-当前方法签名显示您不太可能尝试编写一个。。。此外,您还需要添加“更好”的标准…投票重新打开。。。旁注:我知道大多数人一次读不到一个以上的语句(我就是其中之一:)。因此,让我们尝试一种说法:请提供您选择“最佳方式”的标准-在您的情况下,什么是“更好的”?如何使用Enumerable.Aggregate?放弃.Aggregate(0m,(CurrentAggregatedLineItemAmount,w)=>computeNewAmount(CurrentAggregatedLineItemAmount,w))
。当你完全写出来的时候,它是相同的代码,只是不那么容易理解。
// Create a data structure to model the deductions themselves
public class LineItemDeduction
{
public decimal UnitPriceAmount { get; set; }
public decimal UnitPricePercentage { get; set; }
public decimal LinePriceAmount { get; set; }
public decimal LinePricePercentage { get; set; }
// Assumed that waivers are distinct and are not composed together, only applied on the listed price.
public decimal CalculateWaivedPrice(decimal unitPrice, int qty)
{
return ((unitPrice - UnitPriceAmount - (unitPrice * UnitPricePercentage)) * qty) - LinePriceAmount - (unitPrice * qty * LinePricePercentage);
}
}
// Calculate the deductions
private LineItemDeduction CalculateLineItemDeductionStrategy(LineItemDeduction deduction, Waiver waiver)
{
switch (waiver.Type) {
case 1111:
deduction.UnitPriceAmount += waiver.Amount;
break;
case 2222:
deduction.UnitPricePercentage += waiver.Amount;
break;
case 3333:
deduction.LinePriceAmount += waiver.Amount;
break;
case 4444:
deduction.LinePricePercentage += waiver.Amount;
break;
}
return deduction;
}
// Extension method only for LineItem but it's the same principle for order waivers
public static decimal GetWaivedPrice(this IEnumerable<Waiver> waivers, decimal unitPrice, int qty, Func<LineItemDeduction, Waiver, LineItemDeduction> deductionStrategy)
{
return waivers.Aggregate(
new LineItemDeduction(),
deductionStrategy,
d => d.CalculateWaivedPrice(unitPrice, qty)
);
}
// Now to get the waived price
var waivedPrice = waivers.GetWaivedPrice(unitPrice, qty, CalculateLineItemDeductionStrategy);