在LINQ上调用ToArray选择查询 [英] call ToArray on LINQ select query

查看:183
本文介绍了在LINQ上调用ToArray选择查询的处理方法,对大家解决问题具有一定的参考价值,需要的朋友们下面随着小编来一起学习吧!

问题描述

我有这个查询:

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

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

I'm building an expression tree. I have already build the part inside the GroupBy function and now I would like to call the ToArray method. Here is the code:

    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 = ...行收到一条错误消息:静态方法需要空实例,非静态方法需要非空实例.

I get an error message at the line expr = ...: Static method requires null instance, non-static method requires non-null instance.

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

I already know this error message, but I think, the expression call is correct: I call the ToArray method on outerfieldselector.

你能帮帮我吗?您可以复制并粘贴代码并对其进行测试.您可以根据需要删除比较类.

Could you help me out? You can copy&paste the code and test it. You can remove the compare class, if necessary.

谢谢.

推荐答案

您有几个错误:

  1. 您得到了错误的GroupBy方法.
  2. 对静态方法方法(如GroupByToArray)的调用需要一个空实例,就像错误所说一样.
  1. You're getting the wrong GroupBy method.
  2. Calls to static methods methods like GroupBy and ToArray need a null instance, just like the error says.

这是更正的代码.更改的行是以expr =outerfieldselector =开头并获得GroupBy方法的行:

Here's the corrected code. Lines changed are the lines that begin with expr = and outerfieldselector = and getting the GroupBy method:

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

这篇关于在LINQ上调用ToArray选择查询的文章就介绍到这了,希望我们推荐的答案对大家有所帮助,也希望大家多多支持IT屋!

查看全文
登录 关闭
扫码关注1秒登录
发送“验证码”获取 | 15天全站免登陆