在LINQ选择查询上调用ToArray

时间:2015-01-28 11:35:42

标签: vb.net linq expression-trees toarray

我有这个问题:

Dim test = result.GroupBy(Function(row) groupedindexes.Select(
                                      Function(grpindex) row(grpindex)).ToArray, comp)

我正在构建表达式树。我已经在GroupBy函数中构建了部件,现在我想调用ToArray方法。这是代码:

    Public Function Grouping(ByVal result As IEnumerable(Of Object()), ByVal groupedindexes As List(Of Integer), ByVal comparer As compare) As Expression
        Dim groupbyMethod = GetType(Enumerable).GetMethods(BindingFlags.Public Or BindingFlags.Static).First(Function(m) m.Name = "GroupBy").MakeGenericMethod(GetType(Object()), GetType(System.Collections.Generic.IEqualityComparer(Of Object())))
        Dim convertMethod As MethodInfo = Nothing
        Dim rowParameter = Expression.Parameter(GetType(Object()), "Row")
        Dim indexParameter = Expression.Parameter(GetType(Integer), "grpindex")
        Dim methodstring As String
        Dim expr As Expression = Nothing
        Dim index As Integer
        Dim grpindexes As Expression = Expression.Constant(groupedindexes, GetType(System.Collections.Generic.List(Of Integer)))
        Dim selectMethod = GetType(Enumerable).GetMethods(BindingFlags.Public Or BindingFlags.Static).First(Function(m) m.Name = "Select").MakeGenericMethod(GetType(Integer), GetType(Object))
        Dim toarrayMethod2 = GetType(Enumerable).GetMethods(BindingFlags.Public Or BindingFlags.Static).First(Function(m) m.Name = "ToArray").MakeGenericMethod(GetType(Object))
        Dim cmp As Expression = Expression.Constant(comparer, GetType(compare))

        Dim fieldselector As Expressions.LambdaExpression
        fieldselector = Expression.Lambda(Expression.ArrayAccess(rowParameter, indexParameter), indexParameter)

        Dim outerfieldselector As Expressions.LambdaExpression
        outerfieldselector = Expression.Lambda(Expression.Call(selectMethod, grpindexes, fieldselector), rowParameter)

        expr = Expression.Call(groupbyMethod, Expression.Call(outerfieldselector, toarrayMethod2), cmp)
        Return expr
    End Function

我在第expr = ...行收到错误消息:静态方法需要空实例,非静态方法需要非空实例。

我已经知道此错误消息,但我认为,表达式调用是正确的:我在ToArray上调用了outerfieldselector方法。

你可以帮帮我吗?您可以复制并粘贴代码并进行测试。如有必要,您可以删除比较类。

感谢。

1 个答案:

答案 0 :(得分:0)

你有几个错误:

  1. 您的错误GroupBy方法。
  2. 调用静态方法方法(如GroupByToArray需要一个空实例,就像错误一样。
  3. 这是更正后的代码。更改的行是以expr =outerfieldselector =开头并获取GroupBy方法的行:

    Public Function Grouping(ByVal result As IEnumerable(Of Object()), ByVal groupedindexes As List(Of Integer), ByVal comparer As compare) As Expression
        Dim groupbyMethod = GetType(Enumerable).GetMethods(BindingFlags.Public Or BindingFlags.Static).
            Where(Function(m) m.Name = "GroupBy").
            First(Function(m) m.GetParameters().Count() = 3).
            MakeGenericMethod(GetType(Object()), GetType(Object()))
        Dim convertMethod As MethodInfo = Nothing
        Dim rowParameter = Expression.Parameter(GetType(Object()), "Row")
        Dim indexParameter = Expression.Parameter(GetType(Integer), "grpindex")
        Dim methodstring As String
        Dim expr As Expression = Nothing
        Dim index As Integer
        Dim grpindexes As Expression = Expression.Constant(groupedindexes, GetType(System.Collections.Generic.List(Of Integer)))
        Dim selectMethod = GetType(Enumerable).GetMethods(BindingFlags.Public Or BindingFlags.Static).First(Function(m) m.Name = "Select").MakeGenericMethod(GetType(Integer), GetType(Object))
        Dim toarrayMethod2 = GetType(Enumerable).GetMethods(BindingFlags.Public Or BindingFlags.Static).First(Function(m) m.Name = "ToArray").MakeGenericMethod(GetType(Object))
        Dim cmp As Expression = Expression.Constant(comparer, GetType(compare))
    
        Dim fieldselector As Expressions.LambdaExpression
        fieldselector = Expression.Lambda(Expression.ArrayAccess(rowParameter, indexParameter), indexParameter)
    
        Dim outerfieldselector As Expressions.LambdaExpression
        outerfieldselector = Expression.Lambda(Expression.Call(Nothing, toarrayMethod2, Expression.Call(selectMethod, grpindexes, fieldselector)), rowParameter)
    
        Dim test = Enumerable.GroupBy(result, Function(row) groupedindexes.Select(Function(grpindex) row(grpindex)).ToArray(), comparer)
        expr = Expression.Call(Nothing, groupbyMethod, Expression.Constant(result), outerfieldselector, Expression.Constant(comparer))
    
        Return expr
    End Function