表达式..."LINQ to Entities"仅支持将实体数据模型原始类型转换。

3

我有这个通用方法:

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);
    }

当我使用它时:

List<Person> people = repository.PaginateAndOrderByDesc<Person>(1,
            30, x = > x.RegistrDate)
            .ToList();

我遇到了一个错误:“无法将类型'System.DateTime'强制转换为类型'System.Object'。LINQ to Entities仅支持强制转换EDM基元或枚举类型。”如何使通用函数与orderByDescending表达式一起工作呢?
1个回答

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);
}

话虽如此,我建议不要在此查询中包含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);
}

除了可以让你更自由地组合查询,更重要的是,这能使查询更易读,因为根据调用的方法,查询正在发生的事情非常清晰。


非常感谢,它起作用了!我在互联网上搜索了一半,找不到正确的解决方案。你说得对,保持简单! - Alexander C.
我很感激你花时间提到只做GetPage操作。我总是告诉自己(和其他开发人员),每当你在方法签名中使用"And"或"Or"这样的词语时,都要重新考虑你正在做什么以及为什么在签名中使用条件短语。如果你正在使用条件短语,为什么它们不是单独的操作呢? - akousmata

网页内容由stack overflow 提供, 点击上面的
可以查看英文原文,
原文链接