6

私はコアデータに比較的慣れていません(SQLiteのバックグラウンドから来ました)。「Core Data for iOS」の本を読み終えたばかりですが、次のモデルを持つアプリのモデリングを開始したときに、いくつかの不可解な質問が残っています。

  1. 対多の「トランザクション」関係と「startingBalance」プロパティを持つ「アカウント」エンティティ
  2. 対多の「支払い」関係を持つ「トランザクション」エンティティ (およびアカウントの逆)
  3. 実際に支払われた「金額」の詳細を含む「支払い」エンティティ

パフォーマンス上の理由から、モデルを非正規化し、「Accounts」エンティティに「TotalAmountSpent」プロパティを追加して (本で提案されているように)、何かが変更されたときに単純に更新し続けることができるようにしたいと考えました。

実際には、Core Data でこれを達成するのは難しいようです。これを適切に行う方法がわかりません(正しい方法がわかりません)。だから私の質問は:

a) 代わりに「TotalAmountSpent」を Fetched Property に変更する必要がありますか? パフォーマンスへの影響はありますか (遅延ロードされることはわかっていますが、すべてのアカウントでそのプロパティを取得することはほぼ確実です)。その場合、一定期間 (過去 3 日間など) の「startingBalance」に対する合計支出額を取得できる必要があります。これは SQL では簡単に思えますが、Core Data でこれを行うにはどうすればよいですか? @sum 集計関数を使用できることを読みましたが、@sum を使用して「日付」をフィルタリングするにはどうすればよいですか? また、データを変更するには、取得したプロパティを更新する必要があることも読みました。変更を「聞く」にはどうすればよいですか? 「Payment」エンティティの「willSave」メソッドで行うのですか?

b) 新しい支払いがトランザクションに追加されるたびに、伝播を使用して「TotalAmountSpent」を手動で更新する必要がありますか? これを行うのに最適な場所はどこですか?オーバーライドされた NSManagedObject の「willSave」メソッドでそれを行う必要がありますか? アカウントの「startingBalance」フィールドが更新された場合、対応するすべてのトランザクション/支払いを更新するのは悪夢になるのではないかと心配しています。次に、各支払いを読み込み、合計支出額とアカウントの最終残高を計算する必要があります。何千回も支払いがあったら怖い

この問題に関するガイダンスは大歓迎です。ありがとう!

4

1 に答える 1

8

フェッチされたプロパティを使用する場合、最初にデータをメモリにロードしない限り、そのプロパティを簡単にクエリすることはできません。したがって、代わりに、実際の非正規化データをエンティティに保持することをお勧めします。

これを簡単に最新の状態に保つには、実際にはいくつかの方法があります。

  1. あなたの-awakeFromFetch/-awakeFromInsertで、価値に影響を与える関係のオブザーバーを設定します。次に、KVO(Key Value Observer)が起動したときに、計算を実行してフィールドを更新できます。KVCとKVOを学ぶことは貴重なスキルです。

  2. サブクラスでオーバーライド-willSaveしてNSManagedObject、保存時に計算を行うことができます。これは簡単ですが、保存時にのみ発生し、アカウントオブジェクトが保存される保証がないため、お勧めしません。

いずれの場合も、KVCコレクション演算子を使用して非常に迅速に計算を行うことができます。収集演算子を使用すると、次の呼び出しを介して合計を行うことができます。

NSNumber *sum = [self valueForKeyPath:@"transactions.@sum.startingBalance"];
于 2011-09-27T16:53:39.617 に答える