使用LINQ如何通过“计算字段”进行分组

时间:2008-12-21 02:05:40

标签: c# .net linq .net-3.5 linq-to-entities

我正在使用LINQ to EF并具有以下LINQ查询:

var results = (from x in ctx.Items
               group x by x.Year into decades
               orderby decades.Count() descending
               select new { Decade = decades.Key, DecadeCount = decades.Count() });

所以这种让我到达我想去的地方,因为我得到了按年分解的项目和那一年的项目数。 (即2001年 - 10年,1975年 - 15年,2005年 - 5年,1976年 - 1)我真正想做的事情是将它们分解十年(即2000年代 - 15年代,1970年代 - 16年代)。

如何在Linq语句的group子句的“by”部分中有一个“计算字段”。我认为我想要的基本上是这样的:

var results = (from x in ctx.Items
               group x by (x => x.Year.Value.ToString().Substring(0, 3) + "0s") into decades
               orderby decades.Count() descending
               select new { Decade = decades.Key, DecadeCount = decades.Count() });

或者更一般地说是语法,以便我可以做一些更复杂的评估/计算来进行分组。有什么想法吗?

编辑(更新):

(x => x.Year.Value.ToString()。子字符串(0,3)+“0s”) - 不起作用 - “LINQ to Entities无法识别方法'System.String ToString( )'方法,并且此方法无法转换为商店表达式。“

(x。年/ 10 * 10) - 功能正常(谢谢) - 唯一的“问题”是's'不在最后(即1970年代与1970年代)

有没有把函数放在by子句中?即x组由此组成。管理年(x.Year)到几十年...或... x => x.Year.Value.ToString()。子串(0,3)+“0s”??拥有一些技术(例如调用函数或使用lambda表达式)会很好,这样我就可以覆盖任何我能想到的情况。

再次感谢大家的帮助。

4 个答案:

答案 0 :(得分:7)

您可以使用let子句来避免多次计算数十年:

from x in ctx.Items
group x by (x.Year / 10 * 10) into decades
let decadeCount = decades.Count()
orderby decadeCount descending
select new { Decade = decades.Key, DecadeCount = decadeCount }

答案 1 :(得分:6)

如何按x.Year / 10进行分组? (没有测试过这个!)

var results = (from x in ctx.Items
               group x by (x.Year / 10 * 10) into decades
               orderby decades.Count() descending
               select new { Decade = decades.Key, DecadeCount = decades.Count() });

EDIT1:将(x。年/ 10)更改为(x。年/ 10 * 10)以获得例如1980而不是198。

EDIT2:在你的例子中,“将x由x.Year.Value.ToString()组成。子串(0,3)+”0s“)到几十年”也应该有效。不需要lamba语法。

EDIT3:删除了额外的* 10.感谢Marc!

答案 2 :(得分:2)

看起来我们不能对实体框架上的部分类中定义的计算字段进行分组或选择或类似。

计算字段可用于LINQ to对象(因此您可以将所有数据作为对象返回,然后进行分组)

答案 3 :(得分:0)

我相信您会将SelectMany方法链接到结果的末尾。这将返回IEnumerable的IEnumerable。