实体框架 - 检查是否存在导航属性

发布于 2025-01-18 10:26:21 字数 302 浏览 0 评论 0原文

我有此代码:

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

在某些情况下,与组织Address相关的地址实体可能为null,而这句话给我一个错误,即使地址实体为null,我该怎么办?如果地址为null,有什么办法会带来零且不会出错?

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

I have this code:

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

In some cases the Address entity related to OrganizationAddress can be null and this sentence is giving me an error, how can I do it even if the Address entity is null? is there any way that will bring null and not error if the Address is null?

OrganizationAddress is a list because can have many addresses of different type

如果你对这篇内容有疑问,欢迎到本站社区发帖提问 参与讨论,获取更多帮助,或者扫码二维码加入 Web 技术交流群。

扫码二维码加入Web技术交流群

发布评论

需要 登录 才能够评论, 你可以免费 注册 一个本站的账号。

评论(2

后来的我们 2025-01-25 10:26:21

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

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

I found the solution, I didn't know I can specify the Adress as nullable.

var myAddress = employeeEntity.Organization.OrganizationAddress
.FirstOrDefault(a => (bool)(a.Address?.AddressTypeId).Equals(addressType)).Equals(true));
淡淡離愁欲言轉身 2025-01-25 10:26:21

一种有点奇怪的方法...首先不建议使用没有 OrderByFirstOrDefault ,因为如果您有多个组织地址,则无法保证结果可重复。

总的来说,如果您想查看此组织地址(列表?)是否包含与 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;

这是在处理已加载到内存中的实体时。我在您的方法中看到的问题是,在禁用延迟加载的情况下,Address 可能为 null,例如您的导航属性未声明为 virtual 或支持无代理延迟加载。您找到的解决方案解决了如何处理地址可能为空的情况。我会仔细看看,因为我怀疑在该数据结构中 OrgainzationAddress 中的地址(看起来是多对多连接)表)永远不应该为 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 可能已经在跟踪相关实体的可能性。这是危险的,因为它在运行时完全是主观的,并且可能导致奇怪的间歇性行为,其中某些调用似乎加载了地址,而其他时候即使地址明确存在于数据库中也没有加载地址。当您不急切加载并且未启用延迟加载时,然后获取顶级实体,EF 仍将从当前跟踪的实体池中填充相关实体。这通常会导致实体图的不完整图片,并且会根据 DbContext 当时可能跟踪的相关实体的数量而变化。

A somewhat odd approach... Firstly using FirstOrDefault with no OrderBy is not advisable as the result will not be guaranteed repeatable if you have more than one organization address.

Overall if you want to see if this organizationaddress (list?) contains a matching address with AddressType you could use

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

If your check is more that you what to see if the first organization address is that type, then there should be an OrderBy clause to be deterministic as to which OrganizationAddress is the first one. This could be something like a CreatedDate or a SortOrder to identify which one came first:

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

This is when dealing with an entity that is already loaded in memory. The problem I see with your approach where Address might be null in a case where lazy loading has been disabled, such as your navigation properties are not declared as virtual or supporting proxy-less lazy loading. The solution you found addresses how to handle a situation where the Address might be Null.. I would take a closer look because I would suspect that in that data structure the Address in an OrgainzationAddress (which looks to be a many-to-many joining table) should never be Null.

If lazy loading is enabled and the Address was not eager loaded but accessed and a matching row exists in the database, EF will have executed a query to retrieve it. This has a performance cost (many round trips to the DB as properties are accessed) but trades off with only loading data if and when it is actually needed. If you don't have lazy loading enabled, then the above code is 100% dependent on either a) you remember to eager load the OrganizationAddress and related Address into your employee entity before calling this code:

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

... or b) you are relying on the possibility that EF might already be tracking related entities by the time you read the Employee. This is dangerous because it is completely subjective at runtime and can lead to odd intermittent behaviour where some calls seem to have an Address loaded, while other times no Address is loaded even when one is clearly present in the database. When you don't eager load, and don't have lazy loading enabled, then fetch a top-level entity, EF will still fill in related entities from the pool of entities it is currently tracking. This often results in an incomplete picture of the entity graph and that will vary depending on how many related entities the DbContext might happen to be tracking at the time.

~没有更多了~
我们使用 Cookies 和其他技术来定制您的体验包括您的登录状态等。通过阅读我们的 隐私政策 了解更多相关信息。 单击 接受 或继续使用网站,即表示您同意使用 Cookies 和您的相关数据。
原文