【问题标题】:How to determine if a related child-entity has been included如何确定是否包含相关的子实体
【发布时间】:2017-12-27 09:22:15
【问题描述】:

我有一个使用 ASP.NET Core / EF Core 构建的 Web 应用程序,其中包含两个实体“Products”和“ProductOptions”(一对多关系)。

当我执行查询以从数据库中检索产品时,有没有办法确定是否包含相关的 ProductOptions(产品的子级)? 我需要区分以下几种情况:

案例1:查询中包含了一个Product的相关ProductOptions,但是没有找到ProductOptions

public Product GetByIdIncludingProductOptions(int id)
{
    return DbContext.Products.Include(p => p.ProductOptions).FirstOrDefault(p => p.Id == id);
}

案例 2:一个产品的相关 ProductOptions 根本没有被包含

public Product GetById(int id)
{
    return DbContext.Products.FirstOrDefault(p => p.Id == id);
}

【问题讨论】:

  • @S.Akbari 抱歉,我忘了说明我正在使用延迟加载。我将编辑我的问题以使其更准确。这个问题仍然悬而未决。
  • 目前EF Core中没有延迟加载,所以问题不清楚。
  • @IvanStoev true,我添加了一些代码示例,希望现在更清楚
  • 如何在实体周围创建包装器,其中包含有关查询期间加载的内容的信息?如您所知,GetById 不包含任何内容,而 GetByIdIncludingProductOptions 包含 ProductOptions。使用.Select(p => new ProductWrapper { Entity = p, OptionsLoaded = true/false });修改查询
  • 嗯,不。从某种意义上说,你创造了问题。通过自动初始化列表,您添加了歧义,现在您正试图弄清楚如何删除您添加的歧义。如果您希望开发人员立即知道他们是否忽略了包含,那么您应该将该属性默认为空列表。添加默认值的唯一原因是它未定义的事实并不重要(显然不是这种情况)。

标签: c# asp.net-core entity-framework-core


【解决方案1】:

您可以使用 ChangeTracker 来检查引用是否已加载。您可能想要执行以下操作:

var isLoaded = dbContext.ChangeTracker.Entries<Products>()
    .FirstOrDefault(ee => ee.Entity == product)
    .Reference(e => e.ProductOptions)
    .IsLoaded;

【讨论】:

  • 是的,这是朝着正确方向迈出的一大步。因此,假设我必须在我的 3 层应用程序的 web 层中进行此检查(并在根本不包含相关子实体的情况下抛出异常),如何使用此解决方案优雅地不必将我的数据库层的引用包含到我的网络层中?
  • 为什么要抛出异常?延迟加载是一些意想不到的状态吗?您可以通过调用 Load() 方法来加载相关引用。我建议你看看ChangeTracking namespace 和它的对象。有很多魔法可以帮助你做到这一点!
  • 因为我有一种方法可以根据订单产品的 ProductOptions 确定付款方式的可用性。此方法将产品列表作为参数,并在应用程序的各个点使用。要正确确定可用性,我必须 100% 确定相关的 ProductOptions 已包含在 products-parameter 中。如果不是,我想抛出一个异常,比如“嘿,开发人员,注意:当你执行这个方法时,你必须记住将 ProductOptions 包含到产品参数中”。
  • @Dario 既然你有这个Repository 或任何封装DbContext 的类,只需在其上添加一个方法来检查它。然而,一般来说,你的抽象是有漏洞的——GetById 不应该返回与GetByIdIncludingProductOptions 相同的模型以使其明确。否则毫无意义。
  • @zaitsman:确实如此。如果不启用跟踪,它将无法工作。在这种情况下,他们应该自己照顾。
猜你喜欢
  • 2014-02-17
  • 1970-01-01
  • 2011-10-09
  • 1970-01-01
  • 1970-01-01
  • 2021-10-05
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
相关资源
最近更新 更多