LINQ to Entities无法识别方法“方法名称”方法

我遇到了类似的问题: LINQ to Entities无法识别方法’System.String ToString()’方法,并且此方法无法转换为存储表达式

我正在尝试对我的源进行分页,但在我的情况下,我不能将GetPropertyValue的结果放在变量中,因为我需要x来做到这一点:

 public IEnumerable Paginate(IQueryable source, ref int totalPages, int pageIndex, int pageSize, string sortfield, SortDirection? sortdir) { totalPages = (int)Math.Ceiling(source.Count() / (double)pageSize); if (sortdir == SortDirection.Descending) { return source.OrderByDescending(x => GetPropertyValue(x, sortfield)).Skip(pageIndex * pageSize).Take(pageSize).ToList(); } else { return source.OrderBy(x => GetPropertyValue(x, sortfield)).Skip(pageIndex * pageSize).Take(pageSize).ToList(); } } private static object GetPropertyValue(object obj, string name) { return obj == null ? null : obj.GetType().GetProperty(name).GetValue(obj, null); } 

在这种情况下,我该怎么办?

Lambda表达式(那些在Where,OrderBy等中使用)不能包含任何C#特定代码,它们只能包含表达式树,它被转换为SQL。 你不能在那里调用任何任意方法,除了EF文档提到的那些,如SqlFunctions等。

为了在运行时使用字段名进行排序,您必须在运行时创建一个lambda表达式并将其传递给它。

 public IEnumerable Paginate(IQueryable source, ref int totalPages, int pageIndex, int pageSize, string sortfield, SortDirection? sortdir) { totalPages = (int)Math.Ceiling(source.Count() / (double)pageSize); if (sortdir == SortDirection.Descending) { return source.OrderByDescending(sortfield).Skip(pageIndex * pageSize).Take(pageSize).ToList(); } else { return source.OrderBy(sortfield).Skip(pageIndex * pageSize).Take(pageSize).ToList(); } } public static class QueryableHelper { public static IQueryable OrderBy(this IQueryable q, string name) { Type entityType = typeof(TModel); PropertyInfo p = entityType.GetProperty(name); MethodInfo m = typeof(QueryableHelper).GetMethod("OrderByProperty").MakeGenericMethod(entityType, p.PropertyType); return(IQueryable) m.Invoke(null, new object[] { q, p }); } public static IQueryable OrderByDescending(this IQueryable q, string name) { Type entityType = typeof(TModel); PropertyInfo p = entityType.GetProperty(name); MethodInfo m = typeof(QueryableHelper).GetMethod("OrderByPropertyDescending").MakeGenericMethod(entityType, p.PropertyType); return (IQueryable)m.Invoke(null, new object[] { q, p }); } public static IQueryable OrderByPropertyDescending(IQueryable q, PropertyInfo p) { ParameterExpression pe = Expression.Parameter(typeof(TModel)); Expression se = Expression.Convert(Expression.Property(pe, p), typeof(object)); return q.OrderByDescending(Expression.Lambda>(se, pe)); } public static IQueryable OrderByProperty(IQueryable q, PropertyInfo p) { ParameterExpression pe = Expression.Parameter(typeof(TModel)); Expression se = Expression.Convert(Expression.Property(pe, p), typeof(object)); return q.OrderBy(Expression.Lambda>(se, pe)); } } 

此解决方案仅适用于单一级别的属性,但如果您希望嵌套级别比需要更多工作,可能您可以查看以下SDK来完成所有这些操作。

但是,如果您查看Entity REST SDK本身,它有许多内容以及您可能需要的所有内容。 免责声明:我是作者。

https://entityrestsdk.codeplex.com

您应该动态创建Expression>并将其传递给OrderBy ,而不是使用reflection。

看看这里了解如何创建动态查询。