2011-05-24 47 views
2

我在玩耍,並試圖爲IQueryable做一個擴展方法,通過對象的任意屬性對它進行排序。IQueryable的反射

public static class IQueryableExtender 

{ 

public static IQueryable<TSource> Sort<TSource>(this IQueryable<TSource> query, string orderProperty, string sortDirection = "asc")  
{ 

    var elementType = query.ElementType; 

    var propertyInfo = elementType.GetProperty(orderProperty); 
    if (propertyInfo == null) 
    { 
     throw new ArgumentException(string.Format("{0} is not a property on {1}", orderProperty, elementType.Name)); 
    } 


    switch (sortDirection.ToLower()) 
    { 
     case "asc": 
     case "ascending": 
      return query.OrderBy(x => propertyInfo.GetValue(x, null)); 
      break; 
     case "desc": 
     case "descending": 
      return query.OrderByDescending(x => propertyInfo.GetValue(x, null)); 
      break; 
    } 

    return query; 
} 
} 

我在調用方法時出現此錯誤。我想這與IQueryable尚未執行並檢索任何對象有關。

LINQ to Entities不能識別方法System.Object GetValue(System.Object, System.Object[]),並且此方法無法轉換爲存儲表達式。

我可以通過在IQueryable上執行ToList來解決它,但然後我檢索擴展方法中的數據,這不是我想要的。

這能解決嗎?

回答

2

當您對IQueryable執行LINQ操作時,LINQ to Entities嘗試在數據庫中運行您的查詢> <>。在您的case "asc"中,執行query.OrderBy,LINQ to Entities將其解釋爲「將其轉換爲SQL」,並且由於您使用反射調用,因此它不知道如何轉換爲SQL。

你可以做query.AsEnumerable()。OrderBy(...)。其中一個影響是,當OrderBy操作開始運行時,查詢的其餘部分將執行,以便提供數據。

而不是使用這些反射技巧,您可以簡單地通過使用OrderBy和OrderByDescending方法,旨在讓委託將排序值拉出。 (items.OrderBy(item => item.Property))。你缺少的是在同一個方法中指定升序或降序的能力,但我只是做一對方法,如:

public static IOrderedQueryable<TSource> OrderByAscDesc<TSource, TKey>(
    this IQueryable<TSource> source, 
    Expression<Func<TSource, TKey>> keySelector, bool isAsc 
) { 
    return (isAsc ? source.OrderBy(keySelector) : source.OrderByDescending(keySelector); 
} 

public static IOrderedQueryable<TSource> OrderByAscDesc<TSource, TKey>(
    this IQueryable<TSource> source, 
    Func<TSource, TKey> keySelector, bool ascDesc 
) { 
    return (isDesc ? source.OrderBy(keySelector) : source.OrderByDescending(keySelector); 
} 
+0

感謝您的回答。這不是我想要的。我忽略了我正在使用MVC,並從視圖中獲取屬性的名稱。所以我想要一個方法,我可以只取參數並反映對象的屬性值並對其進行排序。這意味着我不需要任何if語句來選擇使用if語句的屬性。 – Lejdholt 2011-05-24 11:48:52

+0

這使得更有意義。在使用OrderBy之前添加AsEnumerable()應該修復它。 – Jesper 2011-05-24 12:01:02

+0

我會試試看。謝謝 – Lejdholt 2011-05-26 19:39:18