表达式... LINQ to Entities仅支持转换“实体数据模型”原语类型”

Ale*_* C. 3 c# linq linq-to-entities entity-framework

我有这种通用方法:

public IQueryable<TEntity> PaginateAndOrderByDesc<TEntity>(int pageIndex, int pageSize, Expression<Func<TEntity, object>> orderByDescending)
        where TEntity : class, IContextEntity
    {
        int numberOfRecordsToSkip = (pageIndex - 1) * pageSize;

        return context.Set<TEntity>().OrderByDescending(orderByDescending).Skip(numberOfRecordsToSkip).Take(pageSize);
    }
Run Code Online (Sandbox Code Playgroud)

当我使用它时:

List<Person> people = repository.PaginateAndOrderByDesc<Person>(1,
            30, x = > x.RegistrDate)
            .ToList();
Run Code Online (Sandbox Code Playgroud)

我收到一个错误:“无法将类型'System.DateTime'转换为'System.Object'。LINQto Entities仅支持转换EDM基本类型或枚举类型。”

如何使Generic函数与orderByDescending表达式一起使用?

Ser*_*rvy 5

添加一个通用参数来表示要订购的类型:

public IQueryable<TEntity> PaginateAndOrderByDesc<TEntity, TKey>(
    int pageIndex, 
    int pageSize,
    Expression<Func<TEntity, TKey>> sortSelector)
where TEntity : class, IContextEntity
{
    int numberOfRecordsToSkip = (pageIndex - 1) * pageSize;

    return context.Set<TEntity>()
        .OrderByDescending(sortSelector)
        .Skip(numberOfRecordsToSkip)
        .Take(pageSize);
}
Run Code Online (Sandbox Code Playgroud)

话虽如此,我建议不要OrderBy在此查询中包括该方法。它降低了结合“排序数据”和“获取特定页面”操作的查询的可读性。将它们分开。“排序数据”操作就可以了。您实际上只需要创建“获取特定页面”查询:

public static IQueryable<TEntity> GetPage<TEntity>(
    this IOrderedQueryable<TEntity> query,
    int pageIndex,
    int pageSize)
{
    int numberOfRecordsToSkip = (pageIndex - 1) * pageSize;

    return query.Skip(numberOfRecordsToSkip)
        .Take(pageSize);
}
Run Code Online (Sandbox Code Playgroud)

除了使您有能力按自己认为合适的方式来组成查询之外,更重要的是,这会导致查询更具可读性,根据所调用的方法,发生的事情非常清楚。