Asp.net 具有泛型成员表达式的多个排序

Asp.net 具有泛型成员表达式的多个排序,asp.net,vb.net,linq,Asp.net,Vb.net,Linq,编辑2019-01-31: 我按照示例创建了一个带有memberexpressions的通用排序,但我不知道应该如何添加“ThenBy”子句,或者如何在methodcallexpression中组合多个列进行排序。理想情况下,ThenBy应该在skip之前,但它不能,因为它看不到我用methodcallexpression生成的orderby子句。GridSortExpression是一个Telerik类-它只描述查询应该排序的列和方向 有人能解释一下吗?以下是我现在拥有的: Dim exp A

编辑2019-01-31:

我按照示例创建了一个带有memberexpressions的通用排序,但我不知道应该如何添加“ThenBy”子句,或者如何在methodcallexpression中组合多个列进行排序。理想情况下,ThenBy应该在skip之前,但它不能,因为它看不到我用methodcallexpression生成的orderby子句。GridSortExpression是一个Telerik类-它只描述查询应该排序的列和方向

有人能解释一下吗?以下是我现在拥有的:

Dim exp As Expressions.Expression(Of Func(Of Product_Catalog, Boolean)) = PredicateBuilder.True(Of Product_Catalog)()
exp = exp.And(Function(e) e.Chapter_Price > 30)
Dim sortExpression As New List(Of GridSortExpression)({New GridSortExpression() With {.SortOrder = GridSortOrder.Descending, .FieldName = "Id"}})
If sortExpression.Count = 0 Then
     catalogList = con.Product_Catalogs.AsExpandable.Where(exp).OrderBy(Function(o) o.Item_Type).ThenBy(Function(o) o.Item_Description).Skip(startRowIndex).Take(maximumRows).ToList
Else
     Dim param As ParameterExpression = Expression.Parameter(GetType(Product_Catalog), String.Empty)
     Dim prop As MemberExpression = Expression.PropertyOrField(param, sortExpression(0).FieldName)
     Dim sort As LambdaExpression = Expression.Lambda(prop, param)
     Dim source = con.Product_Catalogs.AsExpandable.Where(exp)
     Dim resultExp As MethodCallExpression
     resultExp = Expression.[Call](GetType(Queryable), "OrderBy" & If(sortExpression(0).SortOrder = GridSortOrder.Descending, "Descending", ""), _
         New Type() {GetType(Product_Catalog), prop.Type}, con.Product_Catalogs.AsExpandable.Where(exp).Expression, Expression.Quote(sort))

     catalogList = source.Provider.CreateQuery(Of Product_Catalog)(resultExp).Skip(startRowIndex).Take(maximumRows).ToList
End If

您是否尝试进行排序,有一天您可能会根据1个属性进行排序, 然后在另一天,排序可能基于2个或更多属性

如果是这样的话,您可能需要使用反射来获取属性的数量,然后根据它们的类型对它们进行排序。如果您的目标是能够基于任意数量的属性进行排序,那么这是一个有趣的想法。但是,如果其中一个属性的类型与另一个类的类型相同,该怎么办

我想你可能需要看看

实现不可比较

为了建立自己的例程,做一个排序

这里有一个使用它的示例:>>


但是,这对于您创建的每个类都是特定的。

这里有一种非常通用的方法来进行属性排序,而不必为每个稍有不同的排序实现多个排序比较器

它将允许任意数量的排序“列”(尽管需要稍微增强以支持不同的排序方向)

缺点是它显然不是最有效的,尽管使用调用委托比使用反射更有效。您还需要定义对象属性的通用函数,以便进行排序。通过使其更具体的对象,您可能能够修复该方面

Public Class PropertySortComparer
Implements IComparer

Public Delegate Function GetProp(ByVal obj As Object) As Object
Public SortProps As New List(Of GetProp)

Public Sub New(ParamArray SortMethods() As GetProp)
    Me.SortProps.AddRange(SortMethods)
End Sub

Public Function Compare(x As Object, y As Object) As Integer Implements System.Collections.IComparer.Compare
    For Each gp As GetProp In SortProps
        Dim xVal As Object = gp.Invoke(x)
        Dim yVal As Object = gp.Invoke(y)
        If xVal > yVal Then
            Return 1
        ElseIf xVal < yVal Then
            Return -1
        Else
            'next loop does next property
        End If
    Next
    Return 0
End Function
End Class

Public Module module1
Sub test()
    Dim buffer As New List(Of Rectangle)
    buffer.Add(New Rectangle(34, 55, 40, 30))
    buffer.Add(New Rectangle(34, 55, 45, 38))
    buffer.Add(New Rectangle(34, 56, 46, 30))
    buffer.Add(New Rectangle(34, 70, 45, 30))

    Dim Lst() As Rectangle = buffer.ToArray
    Array.Sort(Lst, New PropertySortComparer(AddressOf Left, AddressOf Top, AddressOf Widht))
    'Lst is now sorted by Left, Top, Width
End Sub

Public Function Left(r As Object) As Object
    Return r.Left
End Function

Public Function Top(r As Object) As Object
    Return r.Top
End Function

Public Function Widht(r As Object) As Object
    Return r.Width
End Function

End Module
公共类属性端口比较器
实现IComparer
公共委托函数GetProp(ByVal obj作为对象)作为对象
作为新列表的公共SortProps(GetProp的)
Public Sub New(ParamArray SortMethods()作为GetProp)
Me.SortProps.AddRange(SortMethods)
端接头
公共函数比较(x为对象,y为对象)作为整数实现System.Collections.IComparer.Compare
对于每个gp,作为SortProp中的GetProp
Dim xVal As Object=gp.Invoke(x)
Dim yVal As Object=gp.Invoke(y)
如果xVal>yVal,则
返回1
ElseIf xVal
显然,这不是针对您的具体情况而构建的,但是这个概念可以根据您的情况进行调整。在大多数情况下,我更喜欢长语法。我发现,当您分配了代码后,快速浏览一下就会更容易理解正在发生的事情。阅读“gp(x)”以后不会告诉我什么,除非我也检查了对象的类型。我还避免使用单行“IF Condition THEN Block”语句,而更喜欢显示更好流的完整多行格式。我很惊讶有多少次我收到关于较短语法形式的评论。特别是因为这个网站的目的是帮助理解代码和整理问题。你可能会认为,真正的目标应该是更多地解释正在发生的事情,而不是总是试图减少击键次数。我确实说过这是一个“次要”的观点。我也只是在确认它编译为相同的代码后才提到它。(委托是用来执行的:-)虽然,这篇文章并不是我在11年时所寻找的,但它可能会帮助有类似问题的人:我对这个问题的理解