问题描述
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
中的相等值有效。由于您是首先按日期部分(无时间)进行订购,因此对于相等的日期,您只需按日期时间进行订购即可,其效果与一天中的时间相同。