EF Core 3无法解析OrderByDescending和ThenBy重删错误

问题描述

  • EF Core 3.1.8
  • Npgsql.EntityFrameworkCore.Postgresql 3.1.4

我实现了以下查询,该查询必须按日期和时间撤消所有评论的组。

var commentsOnPage = await _repository.GetAll()
                .OrderByDescending(c => c.Date.Date)
                .ThenBy(c => c.Date.TimeOfDay)
                .Skip(pageSize * pageIndex)
                .Take(pageSize)
                .ToListAsync();



 public class CommentRepository : GenericRepository<Comment>,ICommentRepository
    {
        private readonly AppDbContext _dbContext;

        public CommentRepository(AppDbContext dbContext) : base(dbContext)
        {
            _dbContext = dbContext;
        }

        public IQueryable<Comment> GetAll() => ((AppDbContext)_dbContext).Comments.AsQueryable();

    }

返回错误

An unhandled exception has occurred while executing the request.
system.invalidOperationException: The LINQ expression 'DbSet<Comment>
    .OrderByDescending(c => c.Date.Date)
    .ThenBy(c => c.Date.TimeOfDay)' Could not be translated. 

解决方法

当前的EF Core查询翻译缺陷之一是缺少所支持内容的文档。更麻烦的是,允许数据库提供程序将翻译添加到他们决定的某些CLR属性/方法中,因此,即使某些LINQ查询为一个数据库提供程序进行翻译,对于另一个数据库提供程序也可能失败。

在这种情况下,不受支持的成员是TimeOfDay。 SqlServer提供程序支持它,但Npgsql不支持。至少Npgsql提供了documentation for supported translations,表明缺少TimeOfDay(不受支持)。

另一方面,Npgsql支持DateTime减运算符(但SqlServer不支持),因此解决Npgsql问题的一种方法是通过从日期时间值中减去日期部分来计算TimeOfDay

.ThenBy(c => c.Date - c.Date.Date)

达到此特定情况(并且应与任何提供程序一起使用)的目标的另一种方法是简单地使用datetime值

.ThenBy(c => c.Date)

这是因为ThenBy仅对OrderBy中的相等值有效。由于您是首先按日期部分(无时间)进行订购,因此对于相等的日期,您只需按日期时间进行订购即可,其效果与一天中的时间相同。