EF Core (LINQ) - 无法翻译查询表达式
EF Core (LINQ) - The Query expression could not be Translated
我有以下按参数搜索记录的查询。
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( outer: DbSet, inner: i =>
EF.Property<Nullable>(i, "ProductID"), outerKeySelector: p =>
EF.Property<Nullable>(p, "ID"), innerKeySelector: (o, i) => new
TransparentIdentifier<Invoice, Product>( Outer = o, Inner = i ))
.Where(i =>
__CurrentDate_0.Subtract(i.Outer.InvoiceDate.AddDays((double)i.Inner.DiscountDays.GetValueOrDefault())).Days > 0)' 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().
有帮助吗?
很可能 EF Core 无法将 Subtract
方法转换为 SQL。根据 this code EF core has a DateTime.AddDays
provider built in but I was unable to find such a provider for Substract
or DateDiff
in the official documentation. So, you can try using EF.Functions which gives you access to 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 以用于 DATEADD
SQL 函数。尝试两种情况。
此外,原始的 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)),
})
我有以下按参数搜索记录的查询。
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( outer: DbSet, inner: i => EF.Property<Nullable>(i, "ProductID"), outerKeySelector: p => EF.Property<Nullable>(p, "ID"), innerKeySelector: (o, i) => new TransparentIdentifier<Invoice, Product>( Outer = o, Inner = i )) .Where(i => __CurrentDate_0.Subtract(i.Outer.InvoiceDate.AddDays((double)i.Inner.DiscountDays.GetValueOrDefault())).Days > 0)' 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().
有帮助吗?
很可能 EF Core 无法将 Subtract
方法转换为 SQL。根据 this code EF core has a DateTime.AddDays
provider built in but I was unable to find such a provider for Substract
or DateDiff
in the official documentation. So, you can try using EF.Functions which gives you access to 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 以用于 DATEADD
SQL 函数。尝试两种情况。
此外,原始的 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)),
})