【问题标题】:multiple Sorts with generic memberexpressions具有通用成员表达式的多个排序
【发布时间】:2011-08-29 19:31:26
【问题描述】:

2019-01-31 编辑:Latest solution

我已经按照示例 here 和 here 创建了一个带有成员表达式的通用排序,但我不知道应该如何添加“ThenBy”子句,或者组合多个列进行排序方法调用表达式。理想情况下,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

【问题讨论】:

标签: asp.net vb.net linq


【解决方案1】:

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

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

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

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

【讨论】:

  • 显然这不是针对您的具体情况而构建的,但该概念可以适应您的情况。
  • 在大多数情况下,我更喜欢长语法。我发现,当您分配代码时,快速浏览一下就更容易理解发生了什么。例如。除非我还检查对象的类型,否则阅读“gp(x)”以后什么都不会告诉我。我还避免使用单行“IF Condition THEN Block”语句,更喜欢显示更好流程的完整多行格式。
  • 我很惊讶有多少次收到关于较短语法形式的 cmets。特别是因为这个站点的目的是帮助理解代码和解决问题。你会认为真正的目标应该是能够解释更多正在发生的事情的格式,而不是总是试图减少按键次数。
  • 我确实说过这是一个“次要”点。我也只是在确认它编译为相同的代码后才提到它。 (并且代表用于执行:-))
【解决方案2】:

您是否正在尝试进行排序,有一天您可以根据 1 个属性进行排序, 那么在另一天,排序可能基于 2 个或更多属性?

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

我想你可能需要看看

实现 IComparable

为了建立自己的例程来进行排序。

这里有一个使用的例子:>>

http://msdn.microsoft.com/en-us/library/4d7sx9hd(VS.80).aspx

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

【讨论】:

    猜你喜欢
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 2019-11-15
    相关资源
    最近更新 更多