【问题标题】:Linq loop through child collection and sum revenueLinq 循环遍历子集合和总收入
【发布时间】:2017-07-11 03:17:54
【问题描述】:

我的结构如下所示:

class Items
{
//item properties
List<Transactions> _ItemTransactions {get;set;}
}

事务类包含以下元素:

class Transactions
{
public int QuantitySoldTotal {get;set;}
public double TransactionPrice {get;set;}
}

我正在尝试将所有项目交易的所有收入加在一起。我试图做这样的事情:

  var totalRevenue = Context.Items.AsParallel().Select(x => x._ItemTransactions.Sum(y => y.TransactionPrice * y.QuantitySoldTransaction)).FirstOrDefault();

但我总是得到 0 值作为回报...有人可以帮我解决这个问题吗?

【问题讨论】:

  • 这一行甚至不应该编译。 Items.AsParallel() 是什么? Items 是一种类型(至少在您显示的代码中)。它有静态的AsParallel 方法吗?如果它是一个列表变量(您只是没有显示),为什么要对所有变量求和然后只取第一个变量?
  • @RenéVogt Items 是一个简单的列表,其中包含来自 DB 的元素...
  • @RenéVogt 我已经更新了我的问题,在项目之前添加了上下文...
  • 仍然不正确,您必须将 Transactions 替换为 _ItemsTransactions
  • @BRAHIMKamel 再次编辑 =)

标签: c# asp.net linq c#-4.0 sum


【解决方案1】:

Linq 有Sum 方法

double totalRevenue = items._ItemTransactions.Sum(transaction => transaction.TransactionPrice * transaction.QuantitySoldTotal);

要汇总列表列表,您可以执行类似的操作

double totalRevenue = Context.Items.Sum(items => items._ItemTransactions.Sum(transaction => transaction.TransactionPrice * transaction.QuantitySoldTotal));

或者

double totalRevenue = Context.Items.SelectMany(items => items._ItemTransactions).Sum(transaction => transaction.QuantitySoldTotal * transaction.TransactionPrice);

【讨论】:

  • 当 Context.Items 本身是一个集合时,我不确定如何访问 _ItemTransactions?我不应该先以某种方式访问​​子节点,然后再进行事务本身吗?
  • @User987 编辑了我的答案
【解决方案2】:
var totalRevenue = Context.Items.AsParallel().Select(x => x.Transactions.Sum(y => y.TransactionPrice * y.QuantitySoldTransaction)).FirstOrDefault();

让我们分解一下你在这里做什么

Context.Items.AsParallel() 并行运行(可能不需要)返回IEnumerable&lt;Item&gt;

.Select(x =&gt; x.Transactions.Sum(y =&gt; y.TransactionPrice * y.QuantitySoldTransaction)) 为列表中的每个项目汇总交易,从而为您留下IEnumerable&lt;double&gt;

.FirstOrDefault();IEnumerable&lt;double&gt; 结果中获取第一项,在您的情况下,它可能偶然总是为零

我猜你想要的是

var totalRevenue = Context.Items
                   .Sum(x => x._ItemTransactions
                              .Sum(y => y.TransactionPrice * y.QuantitySoldTransaction)
                       );

基本上不返回 FirstOrDefault 而是求和

也可以选择

var totalRevenue = Context.Items
                        .SelectMany(x => x._ItemTransactions)
                        .Sum(x => x.QuantitySoldTotal * x.TransactionPrice);

【讨论】:

  • Tocsoft,第一种方法给了我完全错误的结果(我能够在我以前的应用程序版本上进行验证)。将尝试您发布的替代方案 =)
  • 两个 sn-ps 将为相同的输入返回完全相同的值,选择更多的是偏好问题。答案返回所有项目的所有事务的总和,如果这不是你想要的它不清楚。如果这是您想要的,那么代码是正确的,可能是您的旧版本错误。
【解决方案3】:

这应该会给你预期的结果:-

var totalRevenue = Context.Items.SelectMany(x => x._ItemTransactions)
                                .Sum(x => x.QuantitySoldTotal * x.TransactionPrice);

首先使用SelectMany 来展平你的内部列表,即_ItemTransactions,之后你可以简单地调用LINQ Sum 方法来执行求和,就像在普通列表上一样。

【讨论】:

  • @BRAHIMKamel - 没听明白吗?如果 Context.Items 返回一个 Items 的集合,那为什么它不工作呢?
  • 如果是,但 sn-pcode 不是这样
猜你喜欢
  • 1970-01-01
  • 1970-01-01
  • 2018-06-16
  • 2016-07-16
  • 2014-08-13
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
相关资源
最近更新 更多