无法翻译 LINQ DateTimeOffset 表达式

时间:2021-03-29 19:04:51

标签: c# entity-framework linq

我有一个包含属性的 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);

我仍然遇到同样的错误。

1 个答案:

答案 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,因此数据库可以使用索引。