2010-09-29 3 views
1

Можно создать дубликат:
Declaring func<in T,Out Result> dynamicallyсловарь Linq выражения

Я пытаюсь построить запрос, используя LINQ-to-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 не может сортировать элементы этого типа. Мне действительно нужно использовать объект как возвращаемый тип, потому что мне приходится сортировать по широкому кругу типов. Возможно ли немного изменить этот код и заставить его работать?

Спасибо,

Gio

ответ

2

Hm вы должны идти очень низкий уровень в дереве выражения вашего запроса, чтобы сделать такую ​​вещь. Гораздо проще использовать библиотеку 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); 
    } 
} 
Смежные вопросы