我可以在查询表达式语法中指定Queryable.GroupBy(而不是Enumerable.GroupBy)

时间:2013-04-11 12:51:30

标签: vb.net linq expression-trees linq-query-syntax

当我在查询表达式语法中编写Group By时,编译器会自动选择Enumerable.GroupBy作为我的预期目标方法,然后返回IEnumerable而不是IQueryable。这意味着后续的g.Sum来电(我的Select内)需要Func(Of TSource, int)而不是Expression(Of Func(Of TSource, int))。有没有办法强制Group By使用Queryable.GroupBy而是给我一个IQueryable

受控示例代码

Dim myQuery = From x In DataSource.Items
              Group By x.Key Into g = Group
              Select New With {
                  .Key = Key,
                  .RedItems = g.Sum(ItemsOfColor(Colors.Red)) '<== invalid because g.Sum expects a lambda
              }

Private Function PurpleItems(color As Integer) As Expression(Of Func(Of Item, Integer))
    Return Function(item) If(item.Color = color, 1, 0)
End Function

我为什么要这样做? 编译器根据目标变量类型自动在lambda和表达式之间进行转换(即Dim f As Func(Of String, Integer) = Function(x) x.Length()Dim e As Expression(Of Func(Of String, Integer)) = Function(x) x.Length()都有效),因此IEnumerable之间的代码没有明显差异和IQueryable

问题是,LINQ to Entities(我假设其他db支持的LINQ实现)依赖于表达式树来转换为SQL。这意味着IEnumerable lambda版IDbSet的{​​{1}}无法正常工作,就像我在this旧问题中找到的那样。

1 个答案:

答案 0 :(得分:2)

问题在于Queryable.GroupBy()会返回IQueryable<IGrouping<TKey, TSource>>,其中IGrouping<TKey, TSource>实施IEnumerable<TSource>,而不是IQueryable<TSource>

我相信你的代码无论如何都行不通,因为ItemsOfColor()实际上不会被调用。相反,EF会得到一个调用ItemsOfColor()的表达式。由于它不知道该方法,因此会引发异常。