子表中的空外键值不会包含在结果集中

问题描述 投票:0回答:3

我正在使用 ASP.NET Core 创建 Web API。我创建了一种方法来检索不属于指定角色的员工。

考虑此方法实现以返回不属于指定角色的员工。

public async Task<IEnumerable<Employee>> GetEmployeesNotInRoleAsync(int roleId)
{
    var employees = await (from employee in this.dataContext.Employees
                       where employee.RoleId != roleId
                       select new Employee
                       {
                           Id = employee.Id,
                           Name = employee.FullName,
                           Status = employee.Name,
                           RoleId = employee.RoleId,
                        }).ToListAsync().ConfigureAwait(false);
 
    return employees;
}

员工的 RoleId 是可为空的整数。所以,它也可以有空值。

RoleId列是数据库Employees表中可为空的int列,它与EmployeeRoles表中的ID列有外键关系。 我面临的问题是,查询不会返回 RoleId 值为 Null 的员工。请解释一下原因以及如何解决。

即使我使用不带任何where条件的Linq查询从Employees表中检索所有记录,也不会检索到RoleId列为空值的记录。

c# entity-framework linq asp.net-core entity-framework-core
3个回答
2
投票

相关查询将导致 SQL 出现类似于

where RoleId <> ...
的结果,并且当将值与
NULL
进行比较时,在 SQL 中,无法使用比较运算符(例如
NULL
=
)测试
<
值,或
<>
,即当操作数之一为
false
时,此类测试将始终导致
null
,空检查的有效 SQL 语法为
IS [NOT] NULL
,因此,如果您想在查询中包含空值,请尝试更改 LINQ 代码:

from employee in this.dataContext.Employees
where employee.RoleId != roleId || employee.RoleId == null
...

据我所知,至少在后续的 EF Core 版本中,它应该(如果没有明确禁用)开箱即用(但需要检查)。

另请阅读:


0
投票

我认为问题在于延迟加载,查询无法加载相关实体。 您可以尝试使用以下查询进行预加载:

var employees = await (from employee in this.dataContext.Employees.Include('EmployeeRoles')
                   where employee.RoleId != roleId
                   select new Employee
                   {
                       Id = employee.Id,
                       Name = employee.FullName,
                       Status = employee.Name,
                       RoleId = employee.RoleId,
                    }).ToListAsync().ConfigureAwait(false);

return employees;

0
投票

试试这个代码:

public async Task<IEnumerable<Employee>> GetEmployeesNotInRoleAsync(int roleId)
{
    var employees = await dataContext.Employees
        .Where(employee => employee.RoleId != roleId || employee.RoleId == null)
        .Select(employee => new Employee
        {
            Id = employee.Id,
            Name = employee.FullName,
            Status = employee.Name,
            RoleId = employee.RoleId,
        })
        .ToListAsync()
        .ConfigureAwait(false);
 
    return employees;
}
© www.soinside.com 2019 - 2024. All rights reserved.