【问题标题】:EF Core (LINQ) - The Query expression could not be TranslatedEF Core (LINQ) - 无法翻译查询表达式
【发布时间】:2022-02-07 01:49:25
【问题描述】:

我有以下按参数搜索记录的查询。

DateTime CurrentDate = DateTime.Now;
var pastDueInvoices =  Context.Invoice.AsNoTracking()
                .Select(i => new InvoiceDTO
                {
                    ID = i.ID,
                    InvoiceNumber = i.InvoiceNumber
                    DaysPastDue =  i.Balance <= 0 ? 0 : CurrentDate.Subtract(i.InvoiceDate.AddDays(i.ProductNav.DiscountDays.GetValueOrDefault())).Days,
                });

然后我使用此查询仅显示 DaysPastDue > 0 的发票

 if (request.ShowPastDueInvoices)
{                    
  pastDueInvoices =  pastDueInvoices.Where(pd => pd.DaysPastDue > 0);
}

当我搜索过期发票时,我收到以下错误

.Join( 外部:DbSet,内部:i => EF.Property(i, "ProductID"), outerKeySelector: p => EF.Property(p, "ID"), innerKeySelector: (o, i) => new 透明标识符(外部 = o,内部 = i)) .哪里(我=> __CurrentDate_0.Subtract(i.Outer.InvoiceDate.AddDays((double)i.Inner.DiscountDays.GetValueOrDefault())).Days > 0)' 无法翻译。要么以可以翻译的形式重写查询,要么通过以下方式显式切换到客户端评估 插入对 AsEnumerable()、AsAsyncEnumerable() 的调用, ToList() 或 ToListAsync()。

有什么帮助吗?

【问题讨论】:

  • 您的代码必须支持 SQL 查询。所以你不应该使用像减法这样的东西。尝试使用 Ef.Functions 为 in select 编写代码。
  • 您使用的是什么 LINQ:LINQ to Objects / SQL / EF 6.x / EF Core 2.0 / 2.1 / 3.x / 5.x / 6.x?什么数据库提供商?
  • @NetMage 我使用的是 Sql server,NET core 3.1.0
  • 您使用的是什么 LINQ:LINQ to SQL / EF 6.x / EF Core 2.0 / 2.1 / 3.x / 5.x / 6.x?
  • @NetMage 哦抱歉 Linq to EF 6.0

标签: c# asp.net asp.net-mvc linq


【解决方案1】:

很可能 EF Core 无法将 Subtract 方法转换为 SQL。根据this code EF 核心内置了一个DateTime.AddDays 提供程序,但我无法在官方文档中为SubstractDateDiff 找到这样的提供程序。因此,您可以尝试使用 EF.Functions 来访问 DbFunctions class,并使用 SQL 操作的辅助方法 EF.Functions.DateDiffDay

DateTime CurrentDate = DateTime.Now;
var pastDueInvoices =  Context.Invoice.AsNoTracking()
            .Select(i => new InvoiceDTO
            {
                ID = i.ID,
                InvoiceNumber = i.InvoiceNumber
                DaysPastDue =  i.Balance <= 0 ? 0 : EF.Functions.DateDiffDay(CurrentDate, i.InvoiceDate.AddDays(i.ProductNav.DiscountDays.GetValueOrDefault())),
            });

我不确定这个GetValueOrDefault() 方法是否会被翻译成SQL。如果它是您编写的一些自定义扩展方法,则很可能不是。也许您应该尝试将其替换为 i.ProductNav.DiscountDays ?? 0 之类的东西,或者您可能不需要手动将 nullable 天列值转换为 0,SQL 服务器很有可能会直接将空列值转换为0 用于DATEADDSQL 函数。两种情况都试试。

此外,它的原始 EF 6(非核心)版本将使用 DbFunctions

DateTime CurrentDate = DateTime.Now;
var pastDueInvoices =  Context.Invoice.AsNoTracking()
        .Select(i => new InvoiceDTO
        {
            ID = i.ID,
            InvoiceNumber = i.InvoiceNumber
            DaysPastDue =  i.Balance <= 0 ? 0 : DbFunctions.DiffDays(CurrentDate, DbFunctions.AddDays(i.InvoiceDate, i.ProductNav.DiscountDays)),
        })

【讨论】:

    猜你喜欢
    • 1970-01-01
    • 1970-01-01
    • 2021-10-24
    • 2021-12-25
    • 2020-09-10
    • 1970-01-01
    • 1970-01-01
    • 2022-11-11
    • 2022-11-11
    相关资源
    最近更新 更多