EF Core 3.1 查询导致在 Include 中使用的 InvalidOperationException Lambda 表达式无效

EF Core 3.1 Query results in an InvalidOperationException Lambda expression used inside Include is not valid

为什么这个 EF Core 3.1 典型查询会导致:

System.InvalidOperationException: Lambda expression used inside Include is not valid.

(注意:IgnoreQueryFilters() 不是这里的问题。即使没有它,也会导致相同的错误)

var tenant = await context.Tenants.IgnoreQueryFilters()
                .Include(i => i.Locations).ThenInclude(x => x.CurrentResidents.DefaultIfEmpty()).IgnoreQueryFilters()
                .Include(i => i.Locations).ThenInclude(x => x.DefaultResidents.DefaultIfEmpty()).IgnoreQueryFilters()
                .Where(l => l.Id == tenantId)
                .FirstOrDefaultAsync()
                .ConfigureAwait(false);

这是我的 sql 对我要实现的目标的解释:

select t.* from tenants
left join locations l on l.TenantId = t.Id
left join residents c on c.CurrentLocationId = l.Id
left join residents d on d.DefaultLocationId = l.Id
where t.Id = @tenantId

请帮忙。 :祈祷:

您的问题包含 Locations 两次。不确定您 SQL 您要检索的内容。 CurrentLocationId AND DefaultLocationId 匹配 LocationId 的居民?然后在 LINQ 语句中使用 AND。 如果是其他情况,那么 CurrentResidents 和 DefaultResidents 的类型是什么?相同 Resident 类型?那么你可能想要两套... 请提供更多信息...

正如 Felix 指出的那样,问题是您两次包含位置,这在 ef 核心中是不正确的。以下是实现此目标的方法:

var tenant = await context.Tenants
            .IgnoreQueryFilters()
            .Include(i => i.Locations.CurrentResidents.DefaultIfEmpty())
            .Include(i => i.Locations.DefaultResidents.DefaultIfEmpty())
            .FirstOrDefaultAsync(l => l.Id == tenantId, cancellationToken)
            .ConfigureAwait(false);

调用一次 IgnoreQueryFilters 就足够了,你不需要调用它 3 次。

调用 where 和 first 或 default 是不必要的。您可以只使用第一个或默认的 lambda。

这就是我要找的东西:

 var tenant = await context.Tenants
                .IgnoreQueryFilters()
                .Include(i => i.Locations).ThenInclude(x => x.CurrentResidents)
                .Include(i => i.Locations).ThenInclude(x => x.CurrentResidents)
                .FirstOrDefaultAsync(l => l.Id == tenantId)
                .ConfigureAwait(false);

Sql 由 ef core 生成有点奇怪,但会产生我感兴趣的结果,所以一切都很好。

@bencel:感谢您指出这些问题。我专注于获取查询 运行,所以忽略了那些。

谢谢大家!!