使用属性名称作为字符串排序 [英] Sorting using property name as string

查看:108
本文介绍了使用属性名称作为字符串排序的处理方法,对大家解决问题具有一定的参考价值,需要的朋友们下面随着小编来一起学习吧!

问题描述

我希望我的Web API能够按这样的字符串参数对输出进行排序:

http://myapi.com/api/people?skip=0&take=50&orderBy=lastName&descending=true .

因为我的API中还具有分页支持(使用 skip take ),所以我希望 orderBy 下降参数直接应用于SQL查询,以便正确的结果来自数据库.

但是,在执行此操作时,仅尝试使用字符串比较将 orderBy 的参数与我希望排序的类的实际属性进行匹配时,代码将变得非常难以管理.

我找到了解决方案

链接中的解决方案使用的是"Expression.Convert",在大多数情况下,它们不适用于LINQ to Entities.

这是一种有效的扩展方法:

 公共静态IOrderedQueryable< TSource>OrderBy< TSource>(此IQueryable< TSource>源,字符串propertyName){//LAMBDA:x =>x.[PropertyName]var parameter = Expression.Parameter(typeof(TSource),"x");表达式属性= Expression.Property(参数,propertyName);var lambda = Expression.Lambda(property,parameter);//反射:source.OrderBy(x => x.Property)var orderByMethod = typeof(Queryable).GetMethods().First(x => x.Name =="OrderBy"&& x.GetParameters().Length == 2);var orderByGeneric = orderByMethod.MakeGenericMethod(typeof(TSource),property.Type);var result = orderByGeneric.Invoke(null,new object [] {source,lambda});返回(IOrderedQueryable< TSource>)结果;} 

免责声明:我是项目 EF + 的所有者

您可以在我的存储库中找到其他按属性名称排序的方法: GitHub

  • OrderByDescending
  • 然后
  • ThenByDescending
  • AddOrAppendOrderBy
  • AddOrAppendOrderByDescending

编辑:回答子问题

是否可能使用类似以下内容按导航属性进行排序这个,例如属性名称"NavigationProperty.PropertyName"

是的,您可以拆分字符串并循环以使用属性路径创建表达式,也可以使用真实的表达式求值器.

免责声明:我是该项目的所有者 Eval-Expressions.NET

该库允许您动态执行所有LINQ方法.

请参阅: LINQ Dynamic

  var结果= list.OrderByDynamic(x =>"NavigationProperty.PropertyName"); 

I would like my Web API to be able to sort its output by a string parameter such as this one:

http://myapi.com/api/people?skip=0&take=50&orderBy=lastName&descending=true.

Because I also have pagination support (with skipand take) in my API, I would like the orderBy and descending parameter to be applied to the SQL query directly, so that the correct result comes from the database.

When doing this however, the code can become very hard to manage when trying to match the parameters for orderBy with the actual properties of the classes I wish to sort by just using string comparisons.

I have found a solution which is supposed to work with LINQ to Entities and thus also with the new EF7, however when I try to compile this code using the new Core CLR, I get the following message:

Error CS1503 Argument 2: cannot convert from 'System.Linq.Expressions.Expression>' to 'string'

The code from the solution that fails is the OrderBy<T>method:

public static IOrderedQueryable<T> OrderBy<T>(this IQueryable<T> source, string propertyName)
{
    return source.OrderBy(ToLambda<T>(propertyName));
}

It seems like the new Core CLR does not support this attempt. Is there another way to get the solution to work with the new CLR? If no, what other alternatives do I have to enable sorting using EF7 without resulting in countless if or switch statements to compare the input strings to the property names?

解决方案

The solution from your link uses an "Expression.Convert" which most of the time doesn't work with LINQ to Entities.

Here is a working extension method:

public static IOrderedQueryable<TSource> OrderBy<TSource>(this IQueryable<TSource> source, string propertyName)
{
    // LAMBDA: x => x.[PropertyName]
    var parameter = Expression.Parameter(typeof(TSource), "x");
    Expression property = Expression.Property(parameter, propertyName);
    var lambda = Expression.Lambda(property, parameter);

    // REFLECTION: source.OrderBy(x => x.Property)
    var orderByMethod = typeof(Queryable).GetMethods().First(x => x.Name == "OrderBy" && x.GetParameters().Length == 2);
    var orderByGeneric = orderByMethod.MakeGenericMethod(typeof(TSource), property.Type);
    var result = orderByGeneric.Invoke(null, new object[] { source, lambda });

    return (IOrderedQueryable<TSource>)result;
}

Disclaimer: I'm the owner of the project EF+ on GitHub.

You can find other methods to order by property name in my repository: GitHub

  • OrderByDescending
  • ThenBy
  • ThenByDescending
  • AddOrAppendOrderBy
  • AddOrAppendOrderByDescending

EDIT: Answer sub-question

Is it possibly to sort by navigation properties using something like this, e.g. a property name "NavigationProperty.PropertyName"

Yes, you can either split the string and loop to create the expression with the property path or use a real expression evaluator.

Disclaimer: I'm the owner of the project Eval-Expressions.NET

This library allows you to execute all LINQ method dynamically.

See: LINQ Dynamic

var result = list.OrderByDynamic(x => "NavigationProperty.PropertyName");

这篇关于使用属性名称作为字符串排序的文章就介绍到这了,希望我们推荐的答案对大家有所帮助,也希望大家多多支持IT屋!

查看全文
登录 关闭
扫码关注1秒登录
发送“验证码”获取 | 15天全站免登陆