c# - LINQ to Entities 无法识别方法 'Method name' 方法

标签 c# linq iqueryable

我在这里遇到了类似的问题: LINQ to Entities does not recognize the method 'System.String ToString()' method, and this method cannot be translated into a store expression

我正在尝试对源代码进行分页,但就我而言,我无法将 GetPropertyValue 的结果放入变量中,因为我需要 x 来执行那:

public IEnumerable<TModel> Paginate(IQueryable<TModel> 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<TModel> Paginate(IQueryable<TModel> 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<TModel> OrderBy<TModel>(this IQueryable<TModel> q, string name)
    {
        Type entityType = typeof(TModel);
        PropertyInfo p = entityType.GetProperty(name);
        MethodInfo m = typeof(QueryableHelper).GetMethod("OrderByProperty").MakeGenericMethod(entityType, p.PropertyType);
        return(IQueryable<TModel>) m.Invoke(null, new object[] { q, p });
    }

    public static IQueryable<TModel> OrderByDescending<TModel>(this IQueryable<TModel> q, string name)
    {
        Type entityType = typeof(TModel);
        PropertyInfo p = entityType.GetProperty(name);
        MethodInfo m = typeof(QueryableHelper).GetMethod("OrderByPropertyDescending").MakeGenericMethod(entityType, p.PropertyType);
        return (IQueryable<TModel>)m.Invoke(null, new object[] { q, p });
    }

    public static IQueryable<TModel> OrderByPropertyDescending<TModel, TRet>(IQueryable<TModel> q, PropertyInfo p)
    {
        ParameterExpression pe = Expression.Parameter(typeof(TModel));
        Expression se = Expression.Convert(Expression.Property(pe, p), typeof(object));
        return q.OrderByDescending(Expression.Lambda<Func<TModel, TRet>>(se, pe));
    }

    public static IQueryable<TModel> OrderByProperty<TModel, TRet>(IQueryable<TModel> q, PropertyInfo p)
    {
        ParameterExpression pe = Expression.Parameter(typeof(TModel));
        Expression se = Expression.Convert(Expression.Property(pe, p), typeof(object));
        return q.OrderBy(Expression.Lambda<Func<TModel, TRet>>(se, pe));
    }
}

此解决方案仅适用于单一级别的属性,但如果您想要嵌套级别而不需要更多工作,也许您可​​以查看以下 SDK,它可以完成所有这些工作。

但是,如果您看一下 Entity REST SDK 本身,它有很多您可能需要的东西。免责声明:我是作者。

https://entityrestsdk.codeplex.com

关于c# - LINQ to Entities 无法识别方法 'Method name' 方法,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/17977414/

相关文章:

c# - 奇异值分解——社会网络分析

c# - 为什么 DbSet<t>.Where() 默认使用 IQueryable 版本?

c# - 列表查询比 IQueryable 快 20 倍?

c# - 对字符串中存在特定字符的列表进行排序

c# - 单元测试应用程序_开始

c# - .net 字典和查找添加/更新

c# - 按元素划分子列表中的列表

c# - 使用字符分隔符构建具有特定模式的字符串

c# - 如何根据特定条件对 XML 文件中的值求和

c# - 我需要确认我对 IQueryable 和 IEnumerable 的理解