我有一个包含属性的 Order.cs 类:
public string OrderDate { get; set; } = DateTimeOffset.Now.ToString();
我有订单数据库集。使用 EF 我想获得过去 30 天的所有订单。我写了这段代码:
var now = DateTimeOffset.Now;
var orders = _context.Orders.Where(o => ((now - DateTimeOffset.Parse(o.OrderDate)).TotalDays < 30)).ToList();
我收到以下错误:
System.InvalidOperationException: The LINQ expression 'DbSet<Order>
.Where(o => (__now_0 - DateTimeOffset.Parse(o.OrderDate)).TotalDays < 30)' could not be translated. Either rewrite the query in a form that can be translated, or switch to client evaluation explicitly by inserting a call to either AsEnumerable(), AsAsyncEnumerable(), ToList(), or ToListAsync(). See https://go.microsoft.com/fwlink/?linkid=2101038 for more information.
有什么建议可以解决这个问题吗?
编辑
我将 OrderDate 属性更改为
public DateTime OrderDate { get; set; } = DateTime.Now;
LINQ 查询如下:
var atm = DateTime.Now;
var orders = _context.Orders.Where(o => (o.OrderDate - atm).TotalDays < 30);
我仍然遇到同样的错误。
答案 0 :(得分:0)
首先,一定要了解如何date and time handling works in PostgreSQL。根据您在数据库中使用的数据类型、您在 .NET 中使用的数据类型以及您是从 UTC 还是本地时间填充它,您将获得不同的结果。
为了降低错误和歧义的风险,我建议使用 DateTimeOffset
并从 UtcNow
填充它。我还建议为该属性选择一个更好的名称(除非您真的只想存储日期)
public DateTimeOffset OrderTimestamp { get; set; } = DateTimeOffset.UtcNow;
对于查询,您应该反转操作。选择截止时间戳并查询之后的订单。
var earliestTimestamp = DateTimeOffset.UtcNow.AddDays(-30);
var orders _context.Orders.Where(o => o.OrderTimestamp >= earliestTimestamp);
这也会带来性能优势,因为查询变为 sargable,因此数据库可以使用索引。