核心数据获得值的总和。提取属性与传播

时间:2011-09-27 07:13:15

标签: iphone objective-c core-data fetched-property

我对Core Data相对较新(来自SQLite背景)。刚读完“iOS的核心数据”一书,但当我开始为具有以下型号的应用程序建模时,我留下了许多令人费解的问题:

  1. '帐户'实体,具有多对多'交易'关系和'startingBalance'属性
  2. '交易'实体,具有多对多的“付款”关系(与账户相反)
  3. '付款'实体,其中包含实际支付的“金额”
  4. 的详细信息

    出于性能原因,我想对模型进行去规范化,并在“帐户”实体中添加“TotalAmountSpent”属性(如本书所示),这样我就可以在更改内容时继续更新。

    在实践中,这似乎很难通过Core Data实现。我无法弄清楚如何正确地做到这一点(并且不知道正确的方法是什么)。所以我的问题是:

    a)我应该将'TotalAmountSpent'更改为Fetched Property吗?是否有性能影响(我知道它是懒惰加载但我几乎肯定会为每个帐户获取该属性)。如果我这样做,我需要能够在给定的时间段(例如最后三天)内获得花在'startingBalance'上的总金额。这在SQL中看起来很简单,但我如何在Core Data中执行此操作?我读过我可以使用@sum聚合函数但是如何使用@sum过滤'date'?我还读了数据中的任何变化都需要刷新fetched属性。我如何'倾听'改变?我是在“付款”实体的'willSave'方法中做到的吗?

    b)每次将新付款添加到交易时,我是否应该使用传播并手动更新“TotalAmountSpent”?最好的地方是什么?我应该在重写的NSManagedObject的'willSave'方法中做到吗?我担心,如果在帐户上更新了“startingBalance”字段,更新所有相应的交易/付款将是一场噩梦。然后我必须加载每笔付款并计算花费的总金额和帐户的最终余额。如果有数千笔付款,那就吓人了

    非常感谢有关此事的任何指导。谢谢!

1 个答案:

答案 0 :(得分:8)

如果使用fetched属性,则无法在不首先将数据加载到内存中的情况下轻松查询该属性。因此,我建议您在实体中保留实际的非规范化数据。

实际上有几种方法可以轻松保持最新状态。

  1. -awakeFromFetch / -awakeFromInsert设置一个影响价值的关系的观察者。然后,当KVO(键值观察器)触发时,您可以进行计算并更新字段。学习KVC和KVO是一项宝贵的技能。

  2. 您可以覆盖-willSave子类中的NSManagedObject并对保存进行计算。虽然这更容易,但我不推荐它,因为它只会在保存时激活,并且无法保证您的帐户对象将被保存。

  3. 在任何一种情况下,您都可以使用KVC Collection Operators非常快速地进行计算。通过集合运算符,您可以通过调用以下内容来完成总结:

    NSNumber *sum = [self valueForKeyPath:@"transactions.@sum.startingBalance"];