Entity Framework - 检查导航 属性 是否存在

Entity Framework - Check if navigation property is present

我有这个代码:

var myAddress = employeeEntity.Organization.OrganizationAddress
.FirstOrDefault(a => a.Address.AddressTypeId).Equals(addressType)

在某些情况下,与OrganizationAddress相关的Address实体可以为null,这句话给我报错,即使Address实体为null,我该怎么办?如果地址为空,有什么方法可以带来空值而不是错误?

OrganizationAddress 是一个列表,因为可以有许多不同类型的地址

我找到了解决方案,我不知道我可以将地址指定为可为空。

var myAddress = employeeEntity.Organization.OrganizationAddress
.FirstOrDefault(a => (bool)(a.Address?.AddressTypeId).Equals(addressType)).Equals(true));

一种有点奇怪的方法...首先使用不带 OrderByFirstOrDefault 是不可取的,因为如果您有多个组织地址,则不能保证重复 table 结果.

总的来说,如果您想查看此组织地址(列表?)是否包含与您可以使用的 AddressType 匹配的地址

var isMyAddress = employeeEntity.Organization.OrganizationAddress
    .Any(a => a.Address != null 
        && a.Address.AddressTypeId == addressType);

如果您的检查更多的是查看第一个组织地址是否是该类型,那么应该有一个 OrderBy 子句来确定哪个 OrganizationAddress 是第一个。这可能类似于 CreatedDate 或 SortOrder,以确定哪个先出现:

var isMyAddress = employeeEntity.Organization.OrganizationAddress
    .OrderBy(oa => oa.CreatedDateTime)
    .FirstOrdefault(a => a.Address?.AddressTypeId) == addressType;

这是在处理已加载到内存中的实体时。我在您的方法中看到的问题是,在禁用延迟加载的情况下,地址可能为空,例如您的导航属性未声明为 virtual 或不支持 proxy-less 延迟加载。您找到的解决方案解决了如何处理地址可能为空的情况。我会仔细查看,因为我怀疑在该数据结构中,OrgainzationAddress 中的地址(看起来是 many-to-many 加入table) 永远不应为 Null。

如果启用延迟加载并且地址不是预加载而是访问并且数据库中存在匹配行,EF 将执行查询来检索它。这会产生性能成本(访问属性时多次往返数据库),但权衡取舍仅在实际需要时加载数据。如果你没有启用延迟加载,那么上面的代码 100% 依赖于 a) 你记得预先加载 OrganizationAddress 和在调用此代码之前将相关地址添加到您的员工实体中:

var employeeEnitity = _dbContext.Employees
    .Include(e => e.Orgainzation)
        .ThenInclude(o => o.OrganizationAddress)
            .ThenInclude(oa => oa.Address)
    .Where(e => e.EmployeeId == employeeId)
    .Single();

... 或 b) 您依赖的可能性是,在您阅读 Employee 时,EF 可能已经在跟踪相关实体。这是危险的,因为它在运行时完全是主观的,并且可能导致奇怪的间歇性行为,其中某些调用似乎加载了地址,而其他时候即使地址明显存在于数据库中也没有加载任何地址。当您不预先加载,也没有启用延迟加载时,然后获取一个 top-level 实体,EF 仍会从它当前正在跟踪的实体池中填充相关实体。这通常会导致实体图的不完整图片,并且会根据 DbContext 当时可能恰好跟踪的相关实体数量而有所不同。