EF Core Lambda 表达式对象引用未设置为多个连接上的对象实例

EF Core Lambda Expression Object Reference not set to an instance of an object on multiple joins

我在使用 Entity framework 核心 lambda 语法查询数据时遇到 NullReferenceException 的奇怪错误。

使用此代码

           var usersWithRights = await _dbContext.TblUsers.Where(x => x.IsInternal).Select(x => new
            {
                RightIds = x.TblInternalUserRoles.FirstOrDefault().Role.TblInternalRoleRights.Select(i => i.RightId).ToList()
            }).ToListAsync();

当我应用 Count 而不是像

这样的 Select 时,相同的代码有效
           var usersWithRights = await _dbContext.TblUsers.Where(x => x.IsInternal).Select(x => new
            {
                RightIds = x.TblInternalUserRoles.FirstOrDefault().Role.TblInternalRoleRights.Count
            }).ToListAsync();

以上使用 Count 的代码给出了准确的计数结果,但我想要 select RightIds。我已经交叉检查记录是否存在于我的数据库中,结果当我使用 Count 查询时,它给了我准确的结果。

我只想问一下Entity framework核心加入数据有没有限制?比如 EF Core 是否允许最大连接数,或者我可以连接任意数量的表?

没有连接限制,但遗憾的是仍有许多 shortcomings/bugs/issues 一些 LINQ 结构的 EF Core 查询转换。

通常您不需要在投影 (Select) 查询中使用 Include / ThenInclude,因为它们会被忽略。但是在这里获得 NRE w/o 它们表示客户端评估尝试(EF Core 3.x 仍然支持客户端对某些构造的评估,并且主要是像这里这样的最终投影),这反过来意味着翻译失败。

问题好像是

x.TblInternalUserRoles.FirstOrDefault().Role.TblInternalRoleRights.Select(i => i.RightId)

即将序列 (x.TblInternalUserRoles) 转换为单个元素 (.FirstOrDefault()),然后获取子序列 (.Role.TblInternalRoleRights).

可行的解决方案是使用 SelectMany 运算符来展平源序列。 FirstOrDefault() 应该被删除(这对我来说毫无意义)或者如果确实需要,用相应的等效序列运算符 Take(1) 代替。

例如

RightIds = x.TblInternalUserRoles
    .SelectMany(ur => ur.Role.TblInternalRoleRights.Select(i => i.RightId))
    .ToList()

RightIds = x.TblInternalUserRoles
    .SelectMany(ur => ur.Role.TblInternalRoleRights, (ur, i) => i.RightId)
    .ToList()

RightIds = x.TblInternalUserRoles
    .SelectMany(ur => ur.Role.TblInternalRoleRights)
    .Select(i => i.RightId)
    .ToList()