首页 > 解决方案 > EF Core 3 在服务器上评估导航属性 null

问题描述

我有个请求

DbContext.Invoices
.Where(x => x.Status != InvoiceStatus.Draft && x.PaymentMethod == PaymentMethod.DirectDebit)
.Where(x => x.DirectDebitFile == null).ToList();

DirectDebitFile是一个反向导航属性。

在 EF Core 2 中运行良好,不确定在最终请求中如何评估它。升级到 EF Core 3 后,此请求不再起作用,并说

System.InvalidOperationException: The LINQ expression 'DbSet<Invoice>
    .Where(i => !(i.IsDeleted))
    .Where(i => i.ClubId == __CurrentUser_ClubId_0)
    .Cast()
    .Where(e => e.FederationId == __CurrentUser_FederationId_1)
    .Cast()
    .Where(e0 => !(e0.Hidden))
    .Cast()
    .Where(e1 => (int)e1.Status != 0 && (Nullable<int>)e1.PaymentMethod == (Nullable<int>)DirectDebit)
    .LeftJoin(
        outer: DbSet<DirectDebitFile>
            .Where(d => !(d.IsDeleted)), 
        inner: e1 => EF.Property<Nullable<long>>(e1, "Id"), 
        outerKeySelector: d => EF.Property<Nullable<long>>(d, "InvoiceId"), 
        innerKeySelector: (o, i) => new TransparentIdentifier<Invoice, DirectDebitFile>(
            Outer = o, 
            Inner = i
        ))
    .Where(e1 => e1.Inner == null)' 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.

我可以重写此查询并通过将评估移至客户端使其工作

DbContext.Invoices
.Include(x=>x.DirectDebitFile)
.Where(x => x.Status != InvoiceStatus.Draft && x.PaymentMethod == PaymentMethod.DirectDebit)
.AsEnumerable()
.Where(x => x.DirectDebitFile == null).ToList();

但在这种情况下,当然,查询将提取所有行,并且过滤 x.DirectDebitFile == null 将在客户端。我希望在服务器上评估此查询,请帮助实现。

标签: ef-core-3.0ef-core-3.1

解决方案


目前,我通过检查连接表字段之一将请求更改为普通 SQL 检查它的方式

AppDbContext.Invoices.Include(x => x.DirectDebitFile)
                .Where(x => x.Status != InvoiceStatus.Draft)
                .Where(x => x.DirectDebitFile.FileName == null);

推荐阅读