首页 > 解决方案 > ElementAtOrDefault 的替代品

问题描述

我的业务逻辑如下。我有CustomerEvents桌子。该表包含CreatedAt列和CustomerId列。我需要检索特定客户的最后一个和上一个事件。关于最后我没有问题。但是前面的怎么办?我试过了ElementAtOrDefault。但它不起作用。我将向您展示我的代码:

PrevReDepDate = context.CustomerEvents.Where(y
        => y.Customer.CustomerId == 123 && y.EventType == "deposit" && y.Again == true)
    .Select(y => y.CreatedAt).OrderByDescending(y => y)
    .ElementAtOrDefault(1),

这没用。在我看来,这是因为 EF 无法在数据库服务器端执行它。这是异常文本:

System.InvalidOperationException:“NavigationExpandingExpressionVisitor”处理 LINQ 表达式“DbSet .ElementAtOrDefault(__p_0)”失败。这可能表示 EF Core 中的错误或限制。有关更多详细信息,请参阅https://go.microsoft.com/fwlink/?linkid=2101433。在 Microsoft.EntityFrameworkCore.Query.Internal.NavigationExpandingExpressionVisitor.VisitMethodCall(MethodCallExpression methodCallExpression)

我对吗?如果是的话,有什么替代方法可以在 ? 的帮助下获取先前的元素ElementAtOrDefault

标签: c#.net-coreentity-framework-core.net-core-3.1

解决方案


你是对的,正如你所猜测的那样,该ElementAtOrDefault方法无法转换为 T-SQL,Linq to Entities 无法识别它。您可以使用SkipandTake方法,如下所示:

.Select(y => y.CreatedAt).OrderByDescending(y => y).Skip(1).Take(1)

作为另一种选择,您也可以使用.ToList()AsEnumerable方法,就像这个答案https://stackoverflow.com/a/60896583/2946329一样,但您应该知道,通过在加载数据后使用它们,使用 Linq 执行任何进一步的操作到对象,在内存中的数据上。因此,如果您关心性能,我不确定在您的情况下使用这种方法是一个不错的选择。


推荐阅读