EF核心Lambda表达式对象引用在多个连接中未设置为对象实例

问题描述 投票:1回答:1

我有一个奇怪的错误,就是 NullReferenceException 而使用Entity框架核心lambda语法查询数据。

使用这段代码

           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 给我准确的计数结果,但我想选择的是 RightIds. 我已经交叉检查记录存在于我的数据库中,结果当我查询使用 Count 它给我准确的结果。

我只是想问,是否有任何限制的Entity框架核心,而连接数据? 像有一个最大数量的连接允许在EF核心或我可以加入任何数量的表?

c# lambda entity-framework-core linq-to-entities
1个回答
1
投票

没有加入限制,但遗憾的是,EF Core查询翻译一些LINQ构造时,仍然存在很多缺点bugsissues。

通常情况下,你不需要 Include ThenInclude 在投影(Select)查询,因为它们被忽略了。但在这里得到NRE wo它们表明客户端评估尝试(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()
© www.soinside.com 2019 - 2024. All rights reserved.