2012-05-03 127 views
2

我有一個小問題,我會盡力詳細解釋這一點。LINQ - 動態表達式OrderBy

在我的系統上,我有一個與EF 4.1一起工作的Generic Repository。 一切都很好,但我在某些情況下遇到問題,我需要通過一些querys來做動態orderBy。

我通過參數的「字符串」表示在我的類的字段收到,做ORDERBY(如「ID」或「描述」)

一些代碼部分:

 public class SomeClass 
     { 
      public int id { get; set; } 
      public string description { get; set; } 
     } 

     // First we define the parameter that we are going to use 
     // in our OrderBy clause. This is the same as "(parameter =>" 
     // in the example above. 
     var param = Expression.Parameter(typeof(SomeClass), "parameter"); 

     // Now we'll make our lambda function that returns the 
     // request.SortingName property by it's name. 
     var expression = Expression.Lambda<Func<SomeClass, int>>(Expression.Property(param, request.SortingName), param); 

那麼,如果「request.SortingName」是類型「int」(id),但是如果我想通過「string」(描述)或其他類型創建orderBy,則此代碼無效。

我改變的表達,使用「對象」:

 var expression = Expression.Lambda<Func<SomeClass, object>>(Expression.Property(param, request.SortingName), param); 

但是當我運行的代碼,編譯器會引發下一個異常:類型System.Int32'的 表達不能被用於返回類型「System.Object的」

如果該屬性字符串類型,異常的類型爲「System.String」的 表達不能被用於返回類型「System.Object的」

換句話說代碼沒有按不適用於「對象」類型。

任何人都知道我該如何解決這個問題?

謝謝你的時間。

+0

不能使用對目標的反射式和查找基於你有,並確定從正確的類型名稱的屬性? –

+1

[動態LINQ OrderBy](http://stackoverflow.com/questions/41244/dynamic-linq-orderby)可能會幫助 – Eranga

回答

6

下面是我如何使用EF4和我在標準開發庫中創建的一些通用方法進行動態排序和分頁。重要的是您用於爲SortBy方法創建Lambda表達式的第二位代碼。

public enum SqlOrderByDirecton 
{ 
    ASC, 
    DESC 
} 

//Derive Lambda Expression from string 

string sortByKey = "BusinessId"; 
string value = "DESC"; 

var p = Expression.Parameter(typeof(T)); 

this.SortBy = Expression.Lambda<Func<T, dynamic>>(Expression.TypeAs(Expression.Property(p, sortByKey), typeof(object)), p).Compile(); 

this.SortOrder = (DevCore.SqlOrderByDirecton)Enum.Parse(typeof(DevCore.SqlOrderByDirecton), value, true); 

public static List<T> SortAndPaginate<T>(IEnumerable<T> query, 
              Func<T, object> sortBy, 
              SqlOrderByDirecton sortOrder, 
              int rowLimit, 
              int startRecord, 
              out int recordCount) 
    { 
     recordCount = query.Count(); 

     List<T> list = new List<T>(); 

     if (sortOrder == SqlOrderByDirecton.ASC) 
     { 
      list = query.OrderBy(sortBy).Skip(startRecord).Take(rowLimit).ToList(); 
     } 
     else 
     { 
      list = query.OrderByDescending(sortBy).Skip(startRecord).Take(rowLimit).ToList(); 
     } 

     return list; 
    } 
+0

好!我修改了我的代碼: Expression.Lambda >(Expression.TypeAs(Expression.Property(param,request.SortingName),typeof(object)),param); 然後我做.Compile();在我的Repository上,它的工作非常完美。 但是...如果我不'編譯'查詢不起作用。你知道什麼是解釋嗎? – HolloW

+0

@HolloW我不是100%確定這是爲什麼 - 我最初從我問的問題,它的工作,我沒有看到它的任何進一步的代碼 - http://stackoverflow.com/questions/9756407/ fun-product-object-property – Rob

+0

@HolloW:這個答案至少值得讚揚:) –