13

错误是

LINQ to Entities 无法识别方法 'System.Object GetValue(System.Object, System.Object[])' 方法,并且此方法无法转换为存储表达式。

我的代码是

public static GridResult GetAllUsers(int count, int tblsize,string sortcreteria)
{
      using (UserEntities entity = new UserEntities())
      {

          var data = entity.User_Details.Take(count)
.OrderBy(i =>.GetType().GetProperty(sortcreteria).GetValue(i,null))
.Skip(tblsize).ToList();
          result.DataSource = data;
          result.Count = entity.User_Details.Count();
      }
      return result;
}

如何使用属性名称作为字符串进行排序?

4

3 回答 3

39

只需将以下扩展添加到您的代码中,您就可以开始了:

using System.Linq;
using System.Linq.Expressions;
using System;

namespace SomeNameSpace
{
    public static class SomeExtensionClass
    {
        public static IQueryable<T> OrderByField<T>(this IQueryable<T> q, string SortField, bool Ascending)
        {
            var param = Expression.Parameter(typeof(T), "p");
            var prop = Expression.Property(param, SortField);
            var exp = Expression.Lambda(prop, param);
            string method = Ascending ? "OrderBy" : "OrderByDescending";
            Type[] types = new Type[] { q.ElementType, exp.Body.Type };
            var mce = Expression.Call(typeof(Queryable), method, types, q.Expression, exp);
            return q.Provider.CreateQuery<T>(mce);
        }
    }

}

用法:

.OrderByField(sortcriteria, true)

编辑:

但是,为了支持该ThenBy方法,以下返回 an 的方法IOrderedQueryable应该处理所有事情:

public static class SomeExtensionClass
{
    private static IOrderedQueryable<T> OrderingHelper<T>(IQueryable<T> source, string propertyName, bool descending, bool anotherLevel)
    {
        var param = Expression.Parameter(typeof(T), "p");
        var property = Expression.PropertyOrField(param, propertyName);
        var sort = Expression.Lambda(property, param);

        var call = Expression.Call(
            typeof(Queryable),
            (!anotherLevel ? "OrderBy" : "ThenBy") + (descending ? "Descending" : string.Empty),
            new[] { typeof(T), property.Type },
            source.Expression,
            Expression.Quote(sort));

        return (IOrderedQueryable<T>)source.Provider.CreateQuery<T>(call);
    }

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

    public static IOrderedQueryable<T> OrderBy<T>(this IQueryable<T> source, string propertyName, bool descending)
    {
        return OrderingHelper(source, propertyName, descending, false);
    }

    public static IOrderedQueryable<T> ThenBy<T>(this IOrderedQueryable<T> source, string propertyName)
    {
        return OrderingHelper(source, propertyName, false, true);
    }

    public static IOrderedQueryable<T> ThenBy<T>(this IOrderedQueryable<T> source, string propertyName, bool descending)
    {
        return OrderingHelper(source, propertyName, descending, true);
    }
}
于 2014-03-06T14:52:02.317 回答
4

您可以尝试使用(有些旧的)动态 LINQ库来执行此操作:

var data = entity.User_Details
    .Take(count)
    .OrderBy(sortcriteria)
    .Skip(tblsize)
    .ToList();

或者,您仍然可以通过首先将对象移动到内存中来使用原始查询对序列进行排序,因为 LINQ to Entities 提供程序无法将对反射 API 的调用转换为 SQL:

var data = entity.User_Details
    .Take(count)
    .Skip(tblsize)
    .AsEnumerable()
    .OrderBy(i => i.GetType().GetProperty(sortcriteria).GetValue(i, null))
于 2013-04-15T11:22:12.500 回答
1

您可能需要使用Expression Trees来构造 Linq 语句OrderBy(x => x.SomeProperty)

为 LINQ/Lambda 创建 OrderBy 表达式

动态创建 LINQ 到实体 OrderBy 表达式

于 2013-04-15T11:36:01.383 回答