开发者

multiple Sorts with generic memberexpressions

Edit 2019-01-31: Latest solution

I've followed examples here and here to create a generic sort with memberexpressions, but I can't figure out how I'm supposed to add a "ThenBy" clau开发者_如何学编程se, or combine multiple columns for sorting in the methodcallexpression. Ideally, the ThenBy should go before skip, but it can't because it can't see the orderby clause that I made with the methodcallexpression. GridSortExpression is a Telerik class - it just describes which column and direction the query should be sorted.

Can anyone shed some light? Here is what I have right now:

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


Here is a very generic way to do property sorting without having to implement multiple sort comparers for each slightly different sort.

it will allow any number of sort "Columns" (though you would need to enhance slightly to support different sort directions)

The drawback is it's obviously not the most efficient, though the use of invoking delegates is far more efficient then using reflection. You also need to define a general function of the properties of the objects that you may want to sort by. By making it more object specific you may be able to fix that aspect...

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


Are you trying to do a sort where one day you may sort based on 1 property, then on another day the sort maybe based on 2 or more properties?

If so you may need to use reflection in order to get the number of properties and then sort them based on their TYPE. It is an interesting idea if your aim is to be able to sort based on any number of properties. However what if one of those properties has the TYPE that it another CLASS, what then?

I think you may need to look at

Implements IComparable

in order to build your own routine to do a Sort.

There is an example of using it here:>>

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

However this would be specific for each Class that you create.

0

上一篇:

下一篇:

精彩评论

暂无评论...
验证码 换一张
取 消

最新问答

问答排行榜