Основные данные: возможно ли массовое обновление? - PullRequest
2 голосов
/ 16 марта 2010

Можно ли выполнять массовые обновления для данного объекта в Базовых данных?

С учетом, например, сущности Person, могу ли я сделать что-то вроде этого:

Person.update(@"set displayOrder = displayOrder + 1 where displayOrder > 5")

Или я могу выбрать только те сущности, которые нужны, а затем перебрать и обновить их по отдельности ???

Спасибо

Ответы [ 5 ]

4 голосов
/ 16 марта 2010

Вы думаете о базовых данных как о SQL. Большая ошибка.

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

Edit01:

Как бы тогда Вы решаете следующую проблему с пользовательским интерфейсом: Вы хотите представить таблицу лиц лица, упорядоченные по «имени». НО ... пользователь может переупорядочить человека лица, показанные в этой таблице И вы хочу, чтобы упорствовал, чтобы сущности теперь сортируются по «имени» + "displayOrder" (или что вы хотите называть это). Где вы поддерживаете значение "displayOrder", если не как атрибут личности лица?

О, я вижу, что вы пытаетесь сделать. Ты делаешь это намного сложнее, чем должно быть. Базовые данные легко справляются с этим типом функции.

Порядок сортировки не является (обычно см. Ниже ) фасетами модели данных, а скорее контроллером представления, т. Е. Это просто временные заказы, используемые для осмысленного отображения данных пользователю. Как таковые они создаются на лету по мере необходимости. В этом случае вы должны создать NSSortDescriptor / s для сортировки по ключам атрибутов, которые вы хотите. Затем установите запрос на выборку, чтобы использовать эти дескрипторы сортировки. Тогда ваша выборка вернет массив с элементами в нужном порядке.

Без суеты, без суеты.

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

Отделение фактических данных от дисплея очень важно в шаблоне проектирования Model-View-Controller на всех основах API iPhone. Вы не хотите включать логику отображения в модель данных и не хотите хранить данные или иметь логику манипулирования данными на дисплее.

Edit02:

В моем случае пользователи должны иметь возможность вернуться к заявке, посмотреть таблица и увидеть лица лиц в том порядке, в котором они их ставят. Как еще Вы можете сделать это, кроме как имея Атрибут displayOrder?

Если вы хотите сохранить заказ как пользовательские данные, вам необходимо включить его в модель данных.

По стечению обстоятельств, у меня просто была такая потребность. Вот как я справился с проблемой для небольшого числа объектов. Это методы подкласса NSMangedObject. Это работает для нескольких сотен легких объектов.

Если у вас есть большое количество тяжелых объектов (тысяч), я предлагаю создать легкий объект для реализации связанного списка. Назовите это OrderEntity. Он будет иметь атрибут индекса, отношение к индексируемому объекту, отношение к предыдущему OrderEntity и отношение к следующему. (Использование облегченного объекта избавляет вас от необходимости разбивать тяжелые объекты, что экономит память и ускоряет все. Вы должны сбивать с индексации индексируемый объект только тогда, когда вам нужно его отобразить.)

Затем вы используете стандартные методы связанного списка для вставки, обмена и перемещения элементов в списке. Затем вы вызываете update для перемещенных объектов, и они вызывают все последующие OrderEntities для обновления своих индексов.

Это может быть так же просто, как иметь метод, который вызывает следующий OrderEntity, передает текущий индекс объекта и сообщает следующему установить его порядок на значениеInIndex + 1. По сути, это та же функция, что и в SQL-выражении, которое вы хотите имитировать (потому что, конечно, логика та же.)

Если вам приходится много делать, создайте подкласс NSManagedObject для обработки индексации и затем наследуйте ваши индексированные классы от этого.

1 голос
/ 17 марта 2010

Невозможно выполнять массовые SQL-подобные обновления с использованием Core Data, вам придется перебирать все ваши объекты, чтобы обновить значения.

Если вы хотите сохранить атрибут displayOrder, вам нужно сохранить его как атрибут в модели данных. Это такая распространенная проблема, что я поражен тем, что для нее пока нет встроенного решения.

1 голос
/ 16 марта 2010

Правильный способ сделать это - вернуть массив всех объектов Person (просто сделайте запрос выборки для всех объектов Person без указания предиката).

Затем используйте метод NSArray makeObjectsPerformSelector: withObject: чтобы применить массовое изменение - вам может понадобиться создать собственный метод для объекта, чтобы он выполнял точное требуемое изменение.

Затем вызовите save для вашего NSManageObjectContext, и ваши изменения будут сохранены.

Как отмечали другие, это не похоже на SQL, когда вы выпускаете текстовые обновления - но это не значит, что вы все еще не можете выполнять пакетные изменения.

1 голос
/ 16 марта 2010

Нет, вы не можете делать «массовые» обновления в Core Data. Если вы думаете, что хотите это сделать, вы в основном упускаете из виду основные данные: это , а не механизм реляционных данных, это механизм механизма управления графами. Массовые обновления, как вы описываете, это то, что вы делаете с таблицами данных. Итерация по графу объектов - это то, что вы делаете, хорошо, механизм управления графами объектов.

Когда ваши данные действительно являются табличными (как, возможно, ваши), Базовые данные могут быть не лучшим вариантом. Проблема массовых обновлений была одной из причин, по которой Brent Simmons отключил от Core Data для некоторых приложений. Как всегда, используйте правильный инструмент для правильной работы.

В этом случае, вероятно, есть лучший способ сделать то, что вы хотите. Порядок отображения на самом деле не является свойством модели; это более правильно вид собственности. Вы, вероятно, хотите создать извлеченное свойство, которое сортирует что-то правильно в модели. Если это дата, имейте свойство date. Если это предпочтение порядка отображения, вы можете сохранить элементы в графе стиля связанного списка, где каждый экземпляр имеет отношения предыдущий / следующий. Это легко обновить, а также легко отобразить их (последовательная операция).

0 голосов
/ 16 марта 2010

Вы не можете сделать это, по крайней мере, не обойдя всю иерархию объектов Core Data (что на самом деле действительно не рекомендуется).

Добро пожаловать на сайт PullRequest, где вы можете задавать вопросы и получать ответы от других членов сообщества.
...