Building OrderBy-expression at runtime by property-name which can be nested

人盡茶涼 提交于 2020-01-05 07:36:20

问题


How can I dynamically build an order-by expression when only knowing the name of the property (or even the name of a sub-property)?

What I'm trying to achieve is something like:

dbResult = // some database-query as IQueryable<TSource> which is not yet executed;

if (!string.IsNullOrEmpty(request.OrderBy)) { // the user want's to group the results
    var grouped = dbResult.GroupBy(/* this should be build dynamically */);
}

I need something to start with as GroupBy is awaiting a Func<TSource, TKey> but I only know TKey at runtime which can be string, int or even a Guid.

The user could pass something like "Country.Name" to the request.OrderBy property which means the results should be grouped by a sub-property (sub-select), the name of a country.

I think ExpressionTrees is the way to go here but I'm stuck before even getting started as I don't know how to handle the unknown Type as well as the option to group by a property of a sub-select/sub-property.


回答1:


Here is how you can build dynamically a GroupBy expression/query:

public static class QueryableExtensions
{
    public static IQueryable GroupByMember(this IQueryable source, string memberPath)
    {
        var parameter = Expression.Parameter(source.ElementType, "x");
        var member = memberPath.Split('.')
            .Aggregate((Expression)parameter, Expression.PropertyOrField);
        var selector = Expression.Lambda(member, parameter);
        var groupByCall = Expression.Call(typeof(Queryable), "GroupBy",
            new Type[] { parameter.Type, member.Type },
            source.Expression, Expression.Quote(selector));
        return source.Provider.CreateQuery(groupByCall);
    }
}

The problem is though that there is no good generic way of representing the result. And working with non generic IQueryable / IEnumerable is not easy because almost all LINQ methods operate on generic interfaces. Especially with IQueryable you'll find that you need creating more and more methods like this, so you might consider using Dynamic LINQ package.



来源:https://stackoverflow.com/questions/40246515/building-orderby-expression-at-runtime-by-property-name-which-can-be-nested

易学教程内所有资源均来自网络或用户发布的内容,如有违反法律规定的内容欢迎反馈
该文章没有解决你所遇到的问题?点击提问,说说你的问题,让更多的人一起探讨吧!