2010-09-29 53 views
1

可能重複:
Declaring func<in T,Out Result> dynamically詞典LINQ表達式的

我試圖使用LINQ到SQL來建立一個查詢,以提供排序功能,我寫的像這樣:

private Dictionary<string, Expression<Func<DataAccess.Auditing, object>>> OrderDict { get; set; } 


OrderDict = new Dictionary<string,Expression<Func<Augeos.GereonWeb.DataAccess.Auditing, object>>>(); 
OrderDict.Add("Date", p => (DateTime)p.RequestDateTime); 
OrderDict.Add("Username", p => (string)p.CdUsername); 
OrderDict.Add("Portfolio", p => (string)p.CdPortfolio); 
OrderDict.Add("Url", p => (string)p.RequestedUrl); 
OrderDict.Add("Result", p => (bool)p.RequestResult); 
OrderDict.Add("Duration", p => (float)p.RequestDuration); 


private IQueryable<DataAccess.Auditing> SetOrder(string orderBy, bool orderDirection, IQueryable<DataAccess.Auditing> query) 
{ 
    if (orderDirection) 
    return query.OrderByDescending(OrderDict[orderBy]); 
    else 
    return query.OrderBy(OrderDict[orderBy]); 
} 

我的目標是使用SortOrder函數來排序查詢。主要的問題是Func返回一個對象,而linq不能對這種類型的元素進行排序。我真的需要使用對象作爲返回類型,因爲我必須按照各種類型進行排序。實際上是否可以稍微修改此代碼並使其正常工作?

謝謝

吉奧

回答

2

嗯,你不得不去查詢的表達式樹做這樣的事情非常低的水平。一個更簡單的方法是使用DynamicLinq庫,在那裏你可以做一個列作爲字符串值的.OrderBy()。文檔可以找到here on Scott Guthrie's blog

0

如果你想象訂購查詢,像這樣:

query = orderDict["Date"](query, true); 

然後你的字典就必須這樣定義:

var orderDict = new Dictionary<string, Func<IQueryable<Auditing>, bool, IQueryable<Auditing>>>(); 

,你可以像這樣添加項目:

orderDict.Add("Date", MakeOrderedQueryDelegate(a => a.RequestDateTime)); 
orderDict.Add("UserName", MakeOrderedQueryDelegate(a => a.CdUsername)); 

哪一個需要MakeOrderedQueryDelegate是這樣的:

private Func<IQueryable<Auditing>, bool, IQueryable<Auditing>> MakeOrderedQueryDelegate<T>(Expression<Func<Auditing, T>> keyselector) 
{ 
    return (q, descending) => { return MakeOrderedQuery(q, descending, keyselector); }; 
} 

..和你可以這樣實現MakeOrderedQuery:

private IQueryable<Auditing> MakeOrderedQuery<T>(IQueryable<Auditing> query, bool descending, 
    Expression<Func<Auditing, T>> keyselector) 
{ 
    if (descending) 
    { 
     return query.OrderByDescending(keyselector); 
    } 
    else 
    { 
     return query.OrderBy(keyselector); 
    } 
}