Базовые данные получают сумму значений. Полученные свойства против распространения - PullRequest
5 голосов
/ 27 сентября 2011

Я относительно новичок в Core Data (из опыта SQLite).Только что закончил читать книгу «Базовые данные для iOS», но у меня остался ряд непонятных вопросов, когда я начал моделировать приложение, имеющее следующую модель:

  1. Сущность «Счета», которая имеетко-многим отношения «транзакции» и свойство «initialBalance»
  2. сущность «Транзакция», которая имеет отношение ко-многим «платежи» (и обратная к счетам)
  3. сущность «Платеж»который содержит подробную информацию о фактической «сумме», выплаченной

По соображениям производительности я хотел отменить нормализацию модели и добавить свойство «TotalAmountSpent» в сущность «Счета» (как предложено в книге)так что я мог просто продолжать обновлять это, когда что-то изменилось.

На практике это кажется трудным сделать с Core Data.Я не могу понять, как сделать это правильно (и не знаю, как это правильно).Итак, мои вопросы:

a) Должен ли я вместо этого заменить TotalAmountSpent на извлеченное свойство?Есть ли последствия для производительности (я знаю, что она загружается лениво, но я почти наверняка получу это свойство для каждой учетной записи).Если я это сделаю, я должен иметь возможность получить общую сумму, потраченную на начальный баланс за определенный период времени (например, за последние три дня).Это кажется простым в SQL, но как мне сделать это в Core Data?Я прочитал, что могу использовать агрегатную функцию @sum, но как мне отфильтровать по дате с помощью @sum?Я также прочитал, что любое изменение в данных потребует обновления свойства fetched.Как я «слушаю» изменения?Делать ли я это в методе willSave сущности «Платеж»?

b) Должен ли я использовать распространение и вручную обновлять «TotalAmountSpent» каждый раз, когда в транзакцию добавляется новый платеж?Что было бы лучшим местом для этого?Должен ли я сделать это в переопределенном методе willSave NSManagedObject?Я боюсь, что это будет кошмар, чтобы обновить все соответствующие транзакции / платежи, если в учетной записи было обновлено поле «начальный баланс».Затем мне нужно будет загрузить каждый платеж и рассчитать общую потраченную сумму и окончательный остаток на счете.Страшно, если есть тысячи платежей

Любые рекомендации по этому вопросу будет принята с благодарностью.Спасибо!

1 Ответ

8 голосов
/ 27 сентября 2011

Если вы используете извлеченное свойство, вы не сможете легко запросить это свойство без предварительной загрузки данных в память. Поэтому я рекомендую вместо этого хранить фактические ненормализованные данные в объекте.

На самом деле есть несколько способов легко обновлять это.

  1. В вашем -awakeFromFetch / -awakeFromInsert установите наблюдателя отношений, которые будут влиять на значение. Затем, когда срабатывает KVO (Key Value Observer), вы можете выполнить расчет и обновить поле. Изучение KVC и KVO - ценный навык.

  2. Вы можете переопределить -willSave в подклассе NSManagedObject и выполнить расчет при сохранении. Хотя это проще, я не рекомендую его, поскольку он срабатывает только при сохранении, и нет никакой гарантии, что объект вашей учетной записи будет сохранен.

В любом случае вы можете очень быстро выполнить расчет, используя Операторы сбора KVC . С помощью операторов сбора вы можете сделать сумму через звонок на:

NSNumber *sum = [self valueForKeyPath:@"transactions.@sum.startingBalance"];
Добро пожаловать на сайт PullRequest, где вы можете задавать вопросы и получать ответы от других членов сообщества.
...