首页 文章

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

提问于
浏览
5

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

  • 'Accounts'具有多对多'transactions'关系和'startingBalance'属性的实体

  • 'Transaction'具有多对多'payments'关系的实体(与Accounts相反)

  • 'Payment'实体,其中包含实际'amount'已付款的详细信息

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

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

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

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

任何关于此事的指导都将非常感激 . 谢谢!

1 回答

  • 8

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

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

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

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

    在任何一种情况下,您都可以使用KVC Collection Operators非常快速地进行计算 . 通过集合运算符,您可以通过以下方式调用:

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

相关问题