我正在尝试应用一些业务逻辑 关于在以下对象模型上使用LINQ以应用业务逻辑的问题。我相应地填充了以下对象:
public class Waiver
{
public string Id { get; set; }
public int Type { get; set; }
public decimal Amount { get; set; }
}
要应用的业务逻辑:
1.。)应用订单项豁免
如果LineItem豁免[类型]是1111扣除LineItem豁免金额单位价格
如果LineItem豁免[类型]是2222扣除LineItem WaiverAmount作为百分比关闭单位价格
如果LineItem豁免[类型]是3333扣除LineItem豁免金额(线价=数量*单价)
如果LineItem豁免[类型]是4444扣除LineItem豁免金额作为离线价格百分比
2。)申请豁免
如果订单豁免[类型]为4444,则在应用LineItem豁免后扣除订单豁免金额的总订单价格
如果订单豁免[类型]为8888,则在应用LineItem豁免后扣除订单豁免金额作为百分比下单价格
实现这一目标的最佳方法是什么?
GetWaivedPrice(decimal unitPrice, int qty, IEnumerable<Waiver> waiver)
可以将GetWaivedPrice
编写为单个LINQ方法,并为所有折扣类型提供适当的映射吗?
这是我想要实现的,最好是一个写得很好的LINQ方法:
private decimal GetWaivedPrice(decimal unitPrice, int qty,
IEnumerable<Waiver> waiver)
{
//Pseudo code shown for clarifying intent
decimal waivedLineItemAmount = 0m;
if waiver.Select(d => d.Type == 1111)
//then apply the business logic on the unit price accordingly
if waiver.Select(d => d.Type == 2222)
//then apply the business logic on the unit price accordingly
if waiver.Select(d => d.Type == 3333)
//then apply the business logic on the unit price accordingly
return waivedLineItemAmount;
}
答案 0 :(得分:2)
我在这里看不到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;
}
如果你坚持使用LINQ和一个纯函数式的风格,你可以用Enumerable.Aggregate
来表达它,但是这里的一个简单的循环似乎很合适。
答案 1 :(得分:1)
我没有看到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);
答案 2 :(得分:1)
怎么样:
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);
}
当然,您必须使用折扣逻辑更新_logic
字典才能使其正常工作。
答案 3 :(得分:1)
业务规则被隔离成单独的问题(演绎和策略),现在它已经非常LINQ了!
// 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);