代码之家  ›  专栏  ›  技术社区  ›  Slee

linq列表排序方式(myObjects)

  •  7
  • Slee  · 技术社区  · 16 年前

    以下是我目前正在做的事情,效果很好:

    Return returnReports.Skip(PageSize * (PageNumber-1)).Take(PageSize).ToList()
    

    Return returnReports.OrderBy(SortColumn).Skip(skip).Take(PageSize).ToList()
    

    5 回复  |  直到 16 年前
        1
  •  12
  •   Mehrdad Afshari    16 年前

    VB

    Module OrderByExtensions
      <System.Runtime.CompilerServices.Extension()> _
      Public Function OrderByPropertyName(Of T)(ByVal e As IEnumerable(Of T), ByVal propertyName As String) As IOrderedEnumerable(Of T)
        Dim itemType = GetType(T)
        Dim prop = itemType.GetProperty(propertyName)
        If prop Is Nothing Then Throw New ArgumentException("Object does not have the specified property")
        Dim propType = prop.PropertyType
        Dim funcType = GetType(Func(Of ,)).MakeGenericType(itemType, propType)
        Dim parameter = Expression.Parameter(itemType, "item")
        Dim exp = Expression.Lambda(funcType, Expression.MakeMemberAccess(parameter, prop), parameter)
        Dim params = New Object() {e, exp.Compile()}
        Return DirectCast(GetType(OrderByExtensions).GetMethod("InvokeOrderBy", Reflection.BindingFlags.Static Or Reflection.BindingFlags.NonPublic).MakeGenericMethod(itemType, propType).Invoke(Nothing, params), IOrderedEnumerable(Of T))
      End Function
      Private Function InvokeOrderBy(Of T, U)(ByVal e As IEnumerable(Of T), ByVal f As Func(Of T, U)) As IOrderedEnumerable(Of T)
        Return Enumerable.OrderBy(e, f)
      End Function
    End Module
    

    C

    public static class OrderByExtensions
    {
      public static IOrderedEnumerable<T> OrderByPropertyName<T>(this IEnumerable<T> e, string name)
      {
        var itemType = typeof(T);
        var prop = itemType.GetProperty(name);
        if (prop == null) throw new ArgumentException("Object does not have the specified property");
        var propType = prop.PropertyType;
        var funcType = typeof(Func<,>).MakeGenericType(itemType, propType);
        var parameter = Expression.Parameter(itemType, "item");
        var memberAccess = Expression.MakeMemberAccess(parameter, prop);
        var expression = Expression.Lambda(funcType, memberAccess, parameter);
        var x = typeof(OrderByExtensions).GetMethod("InvokeOrderBy", BindingFlags.Static | BindingFlags.NonPublic);
        return (IOrderedEnumerable<T>)x.MakeGenericMethod(itemType, propType).Invoke(null, new object[] { e, expression.Compile() });
      }
      static IOrderedEnumerable<T> InvokeOrderBy<T, U>(IEnumerable<T> e, Func<T, U> f)
      {
        return e.OrderBy(f);
      }
    }
    
        2
  •  3
  •   David Basarab    16 年前

    将排序列作为函数传递。

    public SomeList Foo(Function<Foo, bool> sortFunction, int skip, int PageSize)
    {
       return returnReports.OrderBy(sortFunction).Skip(skip).Take(PageSize).ToList();
    }
    

    这样称呼它

    SomeList(f => f.Bar, 5, 10);
    
        3
  •  2
  •   Community Mohan Dere    8 年前

    如果你使用数据库作为数据源,那么你可以使用 Dynamic LINQ

    如果你正在使用“Linq to objects”,那么你需要创建一个作为参数动态传递的lambda函数。您可以通过使用“Expression.Xyz”方法构建表达式树,然后使用“Compile”方法将表达式树转换为可调用的委托(Func<>类型),您可以将其用作Where的参数。如何构建表达式树的示例可以在 another SO thread here .

        4
  •  1
  •   Jon Skeet    16 年前

    如果你只是被传递了一个字符串,你就不能(轻松地)做到这一点。你可以有一个从字符串到 Func<IEnumerable<Report>, IEnumerable<Report>>

    // Horrible type. Ick.
    private static readonly
        Dictionary<string, Func<IEnumerable<Report>,IEnumerable<Report>>> 
        Orderings = 
        new Dictionary<string, Func<IEnumerable<Report>,IEnumerable<Report>>>
    {
        { "FirstColumn", (IEnumerable<Report> reports) => 
                              reports.OrderBy(report => report.FirstColumn) },
        { "SecondColumn", (IEnumerable<Report> reports) => 
                              reports.OrderBy(report => report.SecondColumn) },
    
        (etc)
    };
    

    然后使用:

    // For production usage, include some error checking!
    return Orderings[sortColumn].Skip(skip).Take(pageSize).ToList();
    

    如果你能得到 SortColumn 在适当的时候通过 Func

        5
  •  0
  •   TheEmirOfGroofunkistan    12 年前

    而不是。OrderBy,您可以使用。排序。只需为您的对象创建一个Comparer类,如下所示 this .

    public class FooComparer : IComparer<Foo>
       {
          private readonly string _sortBy;
          private readonly bool _sortDesc;
    
          public FooComparer(string sortBy)
          {
             _sortBy = sortBy.ToLower();
             _sortDesc = _sortBy.EndsWith(" desc");
             _sortBy = _sortBy.Replace(" asc", string.Empty).Replace(" desc", string.Empty);
          }
    
          //implement IComparer method
          public int Compare(Foo x, Foo y)
          {
             int ret = 0;
    
             switch (_sortBy)
             {
                //must match lowercase sortname 
                case "date":
                   ret = DateTime.Compare(x.SomeDate, y.SomeDate);
                   break;
                //other properties you can sort by as above...
    
             }
    
             //if there is a tie, break it consistently - this will be specific to your object
             if (ret == 0)
             {
                ret = (DateTime.Compare(x.InsertDate, y.InsertDate));
             }
    
             if (_sortDesc)
             {
                ret *= -1;
             }
    
             return ret;
          }
       }
    

    然后排序调用变为:

    Return Foo.Sort(new FooComparer(sortName + " " + sortOrder)
    

    returnReports.Sort(new ReturnReportsComparer(SortColumn));
    
    return returnReports.Skip(skip).Take(PageSize).ToList()
    
    推荐文章