Linq总和对象w / o组

时间:2014-09-04 19:16:30

标签: c# linq

这看起来很简单,但由于某些原因我没有得到它。

假设:

public class Foo
{
    public List<Bar> Bars { get; private set; }
    public Bar Totals { get; private set; }

    public Foo()
    {
        // Blah blah something to populate List of Bars
        this.Bars = new List<Bar>()
        {
            new Bar("Some dude", 50, 1),
            new Bar("Some other dude", 60,25)
        };

        // Calculate Total
        var totals = Bars
            .GroupBy(gb => gb.CustomerName) // When I comment out line i get "Bar does not contain a definition for "Sum" and no extension...."  I want the sum of this without the group.
            .Select(s => new
                {
                    Cost = s.Sum(x => x.Cost),
                    Donation = s.Sum(x => x.Donation),
                }
            ).ToList();

        Totals = new Bar("Totals", totals[0].Cost, totals[0].Donation);

    }

}

public class Bar
{
    public string CustomerName { get; private set; }
    public int Cost { get; private set; }
    public int Donation { get; private set; }
    public int Total { get { return Cost + Donation; } }

    public Bar(string customerName, int cost, int donation)
    {
        this.CustomerName = customerName;
        this.Cost = cost;
        this.Donation = donation;
    }
}

我在这里遇到一些问题:

- 这是组合作的,但如果我通过取出该组,这是我的最终目标我得到&#34; Bar不包含定义为&#34; Sum&#34;没有扩展....&#34;。我想在整个集合中使用这个总和,所以不要一个小组。

- 我在放入Bar之前创建一个anon对象因为我不知道如何在没有无参数构造函数的情况下创建一个Bar(我不能在这个特定的类中添加一个)

- 我不喜欢访问&#34; var totals&#34;使用索引0的数据 - 我最后不应该是ToListing吗?如果没有,我如何访问属性? totals.Cost不起作用。

请帮我弄清楚解决问题的正确方法(特别是本段上面的3个要点)。对于流利的(和一般的linq)语法相当新,我试图找出正确的方法。

编辑:

感谢所有回复。结合几个答案真的让我了解了我的最终目标(但最大的感谢D Stanley)

这就是我现在实施的方式:

public Foo()
{
    // ....

    // Calculate Total
    Totals = new Bar("Totals", Bars.Sum(s => s.Cost), Bars.Sum(s => s.Donation));
}

猜猜我只是让它变得比它需要的更复杂! :o

5 个答案:

答案 0 :(得分:2)

如果删除s,则lambda中的Bar变量的类型为GroupBy。在您的情况下,您希望它是List<Bar>。所以,我认为你想要的是:

var totalCosts = Bars.Sum(x => x.Cost);
var totalDonations = Bars.Sum(x => x.Donation);

答案 1 :(得分:1)

  

我希望在整个集合中使用此总和,因此不需要按组。

然后在集合

上使用Sum
 Bars.Sum(x => x.Cost)
  

在放入Bar之前我正在转换为anon对象因为我不确定如何在没有无参数构造函数的情况下将其强制转换(并且我无法将其添加到此特定类中)

你没有施放,你正在创建匿名对象

  

我不喜欢使用索引0访问“var totals”数据 - 我不应该在结尾处使用ToListing吗?如果没有,我如何访问属性? totals.Cost不起作用。

如果您想要使用单个结果First

答案 2 :(得分:1)

  

但如果我拿出小组,我得到&#34; Bar不包含&#34; Sum&#34;

的定义

那是因为当您取出GroupBy时,您会重复单个项目而不是群组。如果要对整个集合求和,请使用

var totals = new 
        {
            Cost = Bars.Sum(x => x.Cost),
            Donation = Bars.Sum(x => x.Donation),
        }
    ;

或者如果您想要一个包含一个项目的集合,只需更改您的GroupBy

即可
    var totals = Bars
        .GroupBy(gb => true) // trivial grouping
        .Select(s => new Bar
            {
                Cost = s.Sum(x => x.Cost),
                Donation = s.Sum(x => x.Donation),
            }
        ).ToList();
  

-I&#39;在放入Bar之前转换为anon对象因为我不确定如何在没有无参数构造函数的情况下将其强制转换(我无法在此特定类中添加一个)

只需将投影更改为

即可
var totals = new Bar("Totals", Bars.Sum(x => x.Cost), Bars.Sum(x => x.Donation));
  

我不喜欢访问&#34; var totals&#34;使用索引0的数据 - 我最后不应该是ToListing吗?如果没有,我如何访问属性? totals.Cost不起作用。

如果你拿出小组,你最终只得到一个对象。如果你有一个项目的集合,你可以使用First

Totals = new Bar("Totals", totals.First().Cost, totals.First().Donation);

答案 3 :(得分:1)

这很简单,当您执行Bars.Select(s =>时,s的类型为BarBar没有Sum的定义。如果你想要所有的总和而不进行任何分组,你可以这样做:

Bars.Sum(b => b.Cost);
Bars.Sum(b => b.Donation);

答案 4 :(得分:1)

你只需要这个:

Totals = new Bar("Totals", Bars.Sum(o => o.Cost), Bars.Sum(o => o.Donation));