![](/img/trans.png)
[英]An unhandled exception occurred while processing the request. ASP.NET Core MVC
[英]An unhandled exception occurred while processing the request.(Rest api sorting on asp.net)
InvalidOperationException:无法翻译 LINQ 表达式“DbSet().OrderBy(s => s.GetType().GetProperty(__sort_by_0).GetValue(s))”。 以可翻译的形式重写查询,或通过插入对“AsEnumerable”、“AsAsyncEnumerable”、“ToList”或“ToListAsync”的调用显式切换到客户端评估。 有关详细信息,请参阅https://go.microsoft.com/fwlink/?linkid=2101038 。
当我尝试按属性对 rest api 进行排序时,会发生此错误。 在此处输入图像描述
有人在评论中链接了以前的答案,这让我不确定我是否应该回答这个问题,但好吧,它已经写好了。 :)
基本上动态排序比您尝试做的要复杂一些。 即GetType()
、 GetProperty()
等反射代码无法在数据库中执行。
你基本上有两个选择:
使用System.Linq.Dynamic.Core
package(参见文档),您可以提供对实体成员的字符串引用,并将其转换为表达式。
这意味着你可以简单地写这个:
_context.SwiftTransfers.OrderBy(sort_by).ToListAsync();
您可以自己构建表达式。 例如,以下方法支持基于提供的字符串成员名称(可以引用具有“用户/名称/名字”模式的嵌套属性)对IQueryable
应用多个升序或降序:
static IQueryable<T> ApplyOrdering(IQueryable<T> query, string propertyPath, bool isAscending = true, bool firstOrdering = true)
{
var param = Expression.Parameter(typeof(T), "p");
var member = (MemberExpression)propertyPath.Split('/').Aggregate((Expression)param, Expression.Property);
var exp = Expression.Lambda(member, param);
string methodName = isAscending switch
{
true => firstOrdering ? "OrderBy" : "ThenBy",
false => firstOrdering ? "OrderByDescending" : "ThenByDescending"
};
Type[] types = new Type[] { query.ElementType, exp.Body.Type };
var orderByExpression = Expression.Call(typeof(Queryable), methodName, types, query.Expression, exp);
return query.Provider.CreateQuery<T>(orderByExpression);
}
// Then call it like this:
ApplyOrdering(_context.SwiftTransfers.AsQueryable(), sort_by).ToListAsync();
这可以用作IQueryable
上的扩展方法,以更舒适地访问它。
如果您想实现符合标准的排序/过滤方式,您可以查看OData 。 它有现成的包,您可以在 ASP.NET 核心中的端点上应用。 不过,我个人不太喜欢他们的实施建议,因此我通常手动实施符合 OData 的过滤和排序。
如果您使用更改数据形状的 DTO,并且客户端将根据 DTO 向您发送排序参数,您可能会遇到给定属性名称在您尝试排序的实际实体上不存在的问题. 但是,如果您使用 AutoMapper 进行映射,并且如果您通过ProjectTo<TDto>()
,则会自动将表达式转换回来,以便它们引用正确的实体属性。 因此,您不必手动进行属性名称映射。
声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.