Linq Expression Dictionary

Possible duplicate:
Declaration func <in T, Out Result> dynamically

I am trying to build a query using linq-to-sql, and to provide sorting capabilities, I wrote something like this:

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]); } 

My goal is to use the SortOrder function to sort the request. The main problem is that Func returns an object, and linq cannot sort elements of this type. I really need to use the object as a return type, because I have to sort by a wide range of types. Is it possible to modify this code a bit and make it work?

Thanks,

Gio

+1
dictionary c # linq-to-sql
source share
2 answers

Hm you need to go very low level in the expression tree of your query to do such a thing. It is much easier to use the DynamicLinq library, where you can do .OrderBy () with a column as a string value. The documentation can be found here on Scott Guthrie's blog .

+2
source share

If you imagine ordering your request as follows:

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

Then your dictionary should be defined as follows:

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

and you can add elements to it as follows:

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

which requires MakeOrderedQueryDelegate:

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

.. and you can implement MakeOrderedQuery as follows:

 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); } } 
0
source share

All Articles