【问题标题】:Does an object need to know if it's lazy loaded before accessing child在访问子对象之前,对象是否需要知道它是否延迟加载
【发布时间】:2016-04-26 11:01:10
【问题描述】:

假设我们有一个Invoice 对象和InvoiceRow 子对象作为实体框架 模型。

现在我们向Invoice-model 添加一个需要访问行的方法,例如:

invoice.Sum()

如果行没有与发票一起显式加载,则此方法 Sum() 将失败。 处理此问题的最佳方法是什么?

您是否应该在加载实体时“必须记住”include 子对象?或者如果nullSum()-方法本身是否应该显式加载孩子?您还可以在Sum()-方法中对数据库进行新查询,并在其中包含子对象,但如果有未保存的更改怎么办?

【问题讨论】:

  • 这取决于你想要什么。两种方式都有效。您想减少对数据库的查询次数吗?你想最小化加载的数据吗?你想使用 Linq to Entities Sum 方法吗?这完全取决于想要什么。
  • 我认为 Sum() 无法显式加载子对象,因此如果关闭延迟加载并且在调用 Sum() 之前未显式加载子对象,则该方法会失败。
  • @ChrisWyatt 您可以根据Invoice.Id 进行新查询并加载InvoiceRows
  • @Default 那不需要 Invoice 对象引用 DbContext 吗?
  • @ChrisWyatt 不,不是真的。我并不是说要为现有的Invoice 填充InvoiceRows,但是您可以独立地从发票中加载行,然后根据需要对它们进行求和。基本上var rows = context.InvoiceRows.Where(ir => ir.InvoiceId == loadedInvoice.Id);

标签: c# entity-framework model-view-controller


【解决方案1】:

在寻找此类问题的解决方案时,请记住关注点分离。我不希望Invoice 要求访问 DbContext,但它可以知道它是否加载了适当的行(可能通过Any())。

正如 cmets 中所指出的,它确实取决于您的特定用例。你有几个选择:

  1. Invoice 对象本身上有一个Sum() 方法,它汇总了当时可用的所有内容。如果没有子行,这可能会返回 0 或抛出,具体取决于您的需要。此处是否Include 是可选的:如果您的数据相当静态,我会在拉取Invoice 时包含详细信息。使用数据访问层(或类似的),这样您就不会以不同的方法将发票从存储中取出。如果您的数据经常更改,则此方法可能不起作用。
  2. 使用具有Invoice 的单独业务对象,并负责获取详细信息行并对它们求和。这将检查存储库或数据库以确保它具有最新信息,并且如果您的数据可能在您第一次获取 Invoice 后发生更改,则更有用。

关于您的最后一个问题,“如果有未保存的更改怎么办?”:您必须在这里做出业务决策。由于这个例子是一张发票,我可以看到求和的两个原因:获得一个临时总额(想想访问您的购物车以查看您到目前为止花费了多少)或获得最终批准的总额(结账) .首先,可以警告用户存在或可能存在影响总和的未保存更改。其次,您不能允许未保存的更改:您将需要一些东西来检查它们。在发票最终确定之前,您应该强制用户提交或放弃待处理的更改。

【讨论】:

    猜你喜欢
    • 2011-12-19
    • 1970-01-01
    • 1970-01-01
    • 2014-01-19
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 2014-09-19
    相关资源
    最近更新 更多