我仍然对LINQ表示满意,并且尝试将以下foreach循环重构为LINQ等效项。这是我要转换的foreach循环;

var NetTotal = 0M;

foreach (var cheque in ListOfCheques)
{
    var exchangeRate = (from exc in cheque.ExchangeRates
                        where exc.Type == EnumExchangeRate.ForCheque
                        select exc).FirstOrDefault();

    NetTotal = exchangeRate != null ? NetTotal + cheque.NetAmount * exchangeRate.Rate : NetTotal + cheque.NetAmount;
}

return NetTotal ;


以及我提出的LINQ代码;

var NetTotal = (from cheque in ListOfCheques
                join exc in ListOfCheques.SelectMany(b => b.ExchangeRates) on cheque.ID equals exrate.Cheque.ID into chequeWithRate
                where income.ExchangeRates.Select(x => x.Type).Equals(EnumExchangeRate.ForCheque)
                from ur in chequeWithRate.DefaultIfEmpty()
                select ur).Sum(x => x.Cheque.NetAmount * x.Rate);

return NetTotal;


我正在努力的重点;


Check类中的“ ExchangeRates”列表可能不存在,即不需要汇率。
如果没有找到汇率,则应默认为1。我该如何设置...我希望在DefaultIfEmpty(1)中进行设置。


任何帮助是极大的赞赏。

最佳答案

像任何重构一样,只需一点一点地切掉。首先,像这样使用foreach而不是Sum()

return ListOfCheques.Sum(c =>
{
    var exchangeRate = (from exc in c.ExchangeRates
        where exc.Type == EnumExchangeRate.ForCheque
        select exc).FirstOrDefault();
    return c.NetAmount * (exchangeRate ?? new ExchangeRate(){ Rate = 1 }).Rate;
});


(如果ExchangeRate.Rate属性的默认值为1,那就太好了)

我将exchangeRate函数重写为一种简单的格式。确定要FirstOrDefault而不是SingleOrDefault吗?

var exchangeRate = c.ExchangeRates.
    FirstOrDefault(ex => ex.Type == EnumExchangeRate.ForCheque);


然后可以将其交换为第一条语句,将最终结果保留在下面。

如果您希望成为一个班轮!

return ListOfCheques.Sum(c => c.NetAmount *
    (c.ExchangeRates.FirstOrDefault(ex => ex.Type == EnumExchangeRate.ForCheque)
        ?? new ExchangeRate() { Rate = 1 }).Rate);


编辑

澄清??新的ExchangeRate()

与其执行!= null ? (amount * rate) : (rate)而不是我将ExchangeRate对象与一个新的Rate = 1的此类对象合并,我认为这提供了一段更加流畅和整洁的代码。我强烈建议您将默认的Rate设置为1.0,然后只需将new ExchangeRate()合并即可,而无需设置Rate属性。

要在新的ExchangeRate对象中为Rate设置默认值,只需将初始化程序放在构造函数中

class ExchangeRate
{
    public ExchangeRate()
    {
        this.Rate = 1.0;
    }
    // other stuff
}

09-30 13:24