Warning: file_get_contents(/data/phpspider/zhask/data//catemap/2/csharp/311.json): failed to open stream: No such file or directory in /data/phpspider/zhask/libs/function.php on line 167

Warning: Invalid argument supplied for foreach() in /data/phpspider/zhask/libs/tag.function.php on line 1116

Notice: Undefined index: in /data/phpspider/zhask/libs/function.php on line 180

Warning: array_chunk() expects parameter 1 to be array, null given in /data/phpspider/zhask/libs/function.php on line 181
C# 如何编写此LINQ以应用业务逻辑?_C#_Linq_C# 4.0 - Fatal编程技术网

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);