2010-04-01 76 views
2

我怎样才能让一个扩展方法,将工作像这样IQueryable的<T>扩展方法不工作

public static class Extensions<T> 
{ 
    public static IQueryable<T> Sort(this IQueryable<T> query, string sortField, SortDirection direction) 
    { 
     // System.Type dataSourceType = query.GetType(); 

     //System.Type dataItemType = typeof(object); 

     //if (dataSourceType.HasElementType) 
     //{ 
     // dataItemType = dataSourceType.GetElementType(); 
     //} 
     //else if (dataSourceType.IsGenericType) 
     //{ 
     // dataItemType = dataSourceType.GetGenericArguments()[0]; 
     //} 

     //var fieldType = dataItemType.GetProperty(sortField); 
     if (direction == SortDirection.Ascending) 
      return query.OrderBy(s => s.GetType().GetProperty(sortField)); 
     return query.OrderByDescending(s => s.GetType().GetProperty(sortField)); 

    } 
} 

目前,上面写着“扩展方法必须在非泛型静态类中定义”。

我该怎么做?

回答

12

尝试......(但我不知道它会做你想要什么。)

public static class Extensions 
{ 
    public static IQueryable<T> Sort<T>(this IQueryable<T> query, 
              string sortField, 
              SortDirection direction) 
    { 
     if (direction == SortDirection.Ascending) 
      return query.OrderBy(s => s.GetType() 
             .GetProperty(sortField)); 
     return query.OrderByDescending(s => s.GetType() 
              .GetProperty(sortField)); 

    } 
} 

...泛型参数应该在方法上,而不是在类上。将它从Extensions<T>移动到Sort<T>(将允许您摆脱您正在使用的编译器错误。

至于你想用反射做什么,你会返回orderby子句的PropertyInfo对象。这很可能不符合你想要的表达式树。你可能想看看Dynamic LINQ

...这是来自Dynamic LINQ的摘录。

public static IQueryable OrderBy(this IQueryable source, 
             string ordering, 
             params object[] values) { 
    if (source == null) throw new ArgumentNullException("source"); 
    if (ordering == null) throw new ArgumentNullException("ordering"); 
    ParameterExpression[] parameters = new ParameterExpression[] { 
     Expression.Parameter(source.ElementType, "") }; 
    ExpressionParser parser = new ExpressionParser(parameters, 
                ordering, 
                values); 
    IEnumerable<DynamicOrdering> orderings = parser.ParseOrdering(); 
    Expression queryExpr = source.Expression; 
    string methodAsc = "OrderBy"; 
    string methodDesc = "OrderByDescending"; 
    foreach (DynamicOrdering o in orderings) { 
     queryExpr = Expression.Call(
      typeof(Queryable), o.Ascending ? methodAsc : methodDesc, 
      new Type[] { source.ElementType, o.Selector.Type }, 
      queryExpr, Expression.Quote(Expression.Lambda(o.Selector, 
                  parameters))); 
     methodAsc = "ThenBy"; 
     methodDesc = "ThenByDescending"; 
    } 
    return source.Provider.CreateQuery(queryExpr); 
} 
+0

感谢您的答案和额外的链接......我一直试图做动态LINQ整个上午,不知道我真的在做什么。 不能说我现在真的做,要么...需要做一些阅读所有这一切。 再次感谢! – Micah 2010-04-01 20:01:42

+0

我想我们都已经在那里了:o)...祝你好运! – 2010-04-01 20:03:57

+0

顺便说一句,这段代码在这里http://stackoverflow.com/questions/41244/dynamic-linq-orderby确实也有帮助 – Micah 2010-04-01 20:07:41

8

更改此:

public static class Extensions 
{ 
    public static IQueryable<T> Sort<T>(this IQueryable<T> query, string sortField, SortDirection direction) 
    { 
     //code 
    } 
} 

这个班是非通用的,只是你的扩展方法应该是:)

3

错误已经告诉你:

扩展方法必须在非通用静态类中定义。

只需删除泛型类型参数即可。

public static class Extensions // no <T> 
{ 
    // ... 
} 
+0

这个将不会解决问题,该方法还需要添加通用参数:'Sort ' – 2010-04-01 18:37:50

+1

它至少可以解决* one *问题。也许它教导别人实际阅读错误信息......不,我在开玩笑。 – Thomas 2010-04-01 18:51:10

+0

别担心......只是移动泛型参数不会解决他很快会发现的问题。 – 2010-04-01 18:52:08