【问题标题】:Using LINQ on ObservableCollection with GroupBy and Sum aggregate在 ObservableCollection 上使用 LINQ 与 GroupBy 和 Sum 聚合
【发布时间】:2012-04-20 06:29:08
【问题描述】:

我有以下代码块可以正常工作;

var boughtItemsToday = (from DBControl.MoneySpent
            bought in BoughtItemDB.BoughtItems
            select bought);

BoughtItems = new ObservableCollection<DBControl.MoneySpent>(boughtItemsToday);

它从我的 MoneySpent 表中返回数据,其中包括 ItemCategory、ItemAmount、ItemDateTime。

我想将其更改为按 ItemCategory 和 ItemAmount 分组,这样我就可以看到我大部分的钱都花在了哪里,所以我创建了一个 GroupBy 查询,并最终得到了这个;

var finalQuery = boughtItemsToday.AsQueryable().GroupBy(category => category.ItemCategory); 

BoughtItems = new ObservableCollection<DBControl.MoneySpent>(finalQuery);

这给了我 2 个错误;

错误 1 ​​'System.Collections.ObjectModel.ObservableCollection.ObservableCollection(System.Collections.Generic.List)' 的最佳重载方法匹配有一些无效参数

错误 2 参数 1:无法从 'System.Linq.IQueryable>' 转换为 'System.Collections.Generic.List'

这就是我卡住的地方!如何使用 GroupBy 和 Sum 聚合函数在 1 个 LINQ 查询中获取我的类别和相关支出的列表?!

感谢您的任何帮助/建议。

标记

【问题讨论】:

    标签: c# linq group-by sum observablecollection


    【解决方案1】:

    您可以将每个组投影到具有您想要的属性的任何匿名(或者更好地为此创建一个新类型)类:

    var finalQuery = boughtItemsToday.GroupBy(category => category.ItemCategory);
                                     .Select(g => new 
                                      { 
                                         ItemCategory = g.Key, 
                                         Cost = g.Sum(x => x.ItemAmount)
                                      });
    

    根本不需要AsQueryable(),因为boughtItemsToday 无论如何都是IQuerable。您也可以只组合查询:

    var finalQuery = BoughtItemDB.BoughtItems
                                 .GroupBy(item => item.ItemCategory);
                                 .Select(g => new 
                                  { 
                                      ItemCategory = g.Key, 
                                      Cost = g.Sum(x => x.ItemAmount)
                                  });
    

    【讨论】:

    • 他得到的错误是添加到ObservableCollection。他需要选择语句来返回MoneySpent 的列表
    • 与上述帖子的响应相同,突出显示错误;不允许在查询中显式构造实体类型“WP7_CashTrack.DBControl+MoneySpent”。是不是因为构造函数认为它已经被定义了?
    • @MarkOates:您无法投影到 Linq to Entities 中的实体——我的查询改为投影到匿名类——您确定您正在使用此查询吗?您应该定义一个新类,而不是投影到,并将其用作 ObservableCollection 中的类型
    • @BrokenGlass 我不确定我是否跟随你这样做。我想我需要创建一个新类(例如 CatSummary),但我不确定如何将新的摘要数据投影到它?
    【解决方案2】:

    .GroupBy(category =&gt; category.ItemCategory); 返回一个可枚举的 IGrouping 对象,其中每个 IGrouping 的键是不同的 ItemCategory 值,而值是 MoneySpent 对象的列表。因此,您将无法像当前所做的那样简单地将这些分组放入 ObservableCollection 中。

    相反,您可能希望将每个分组结果选择到一个新的 MoneySpent 对象中:

    var finalQuery = boughtItemsToday
        .GroupBy(category => category.ItemCategory)
        .Select(grouping => new MoneySpent { ItemCategory = grouping.Key, ItemAmount = grouping.Sum(moneySpent => moneySpent.ItemAmount);
    
    BoughtItems = new ObservableCollection<DBControl.MoneySpent>(finalQuery);
    

    【讨论】:

    • 感谢您的回复,我已经完全按照您所说的做了,并且它似乎按预期工作,但是它给了我以下错误“实体类型 'WP7_CashTrack.DBControl+MoneySpent' 的显式构造”不允许查询。”这是因为构造函数认为它已经被定义了吗?
    • 看看这个:stackoverflow.com/questions/2952856/…。看起来您可能需要创建一个新的 MoneySpentSummary 样式类来存储类别和总花费。无论如何,这可能是一个更好的设计,因为您不会为了稍微不同的目的重用一个类。
    猜你喜欢
    • 2023-03-30
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    相关资源
    最近更新 更多