iOS Core Data уникальная выборка объектов - PullRequest
2 голосов
/ 02 сентября 2011

Я довольно новичок в iOS / Cocoa, и у меня есть очень фундаментальный вопрос о базовых данных. Я искал в интернете подходящий ответ / решение, но не смог.

Итак, вопрос в том, как вы обрабатываете уникальность основных данных? Я знаю, что данные ядра - это не база данных, а нечто вроде графа объектов. Предположим, у нас есть сущность с именем «Пользователь» с атрибутами «id» и «имя» и несколько отношений с другими сущностями. Теперь мы хотим обновить имя конкретного пользователя (например, веб-сервис дал нам идентификатор и новое имя).

Так я и делал раньше:

NSFetchRequest *request = [[NSFetchRequest alloc] init];
[request setEntity:[NSEntityDescription entityForName:@"User" inManagedObjectContext:context]];
[request setPredicate:[NSPredicate predicateWithFormat:@"id == %@", anId]];

NSError *error = nil;
NSArray *results = [context executeFetchRequest:request error:&error];
User *user = [results lastObject];

Но чем я слышал, это плохая практика. Это потому, что запросы на выборку с предикатами очень медленные? Я не могу себе представить, что это такое большое дело. Насколько я знаю, нет другого способа получить уникальный объект, кроме как пройтись по каждому объекту и проверить на равенство.

Было бы более эффективно извлекать все объекты сущности, помещать их в массив и проходить по нему вручную (вместо запроса на выборку)?

NSFetchRequest *request = [[NSFetchRequest alloc] init];
[request setEntity:[NSEntityDescription entityForName:@"User" inManagedObjectContext:context]];

NSError *error = nil;
NSArray *results = [context executeFetchRequest:request error:&error];

User *resultUser;

for(User *user in results){
    if([user.id isEqual:anId]) resultUser = user;
}

Пожалуйста, помогите мне найти правильный путь и спасибо.

Ответы [ 2 ]

4 голосов
/ 02 сентября 2011

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

1 голос
/ 02 сентября 2011

Вы выбираете не уникальный объект, а объекты, содержащие условно уникальное значение атрибута.

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

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

Я думаю, что вы прочитали предупреждения о том, что пытаться втиснуть значения ключей, подобные SQL, в сущности, а затем попытаться связать управляемые объекты вместе с этими ключами с помощью предикатов, например, сделать что-то вроде:

EntityOne{
  sqlKey:string
}

EntityTwo{
  sqlKey:string
}

… и затем пытается связать объекты двух сущностей с предикатами.

   (anEntityOneObject.)sqlKey == anEntityTwoObject.sqlKey

… вместо того, чтобы просто установить отношение в модели данных.

EntityOne{
  two<-->EntityTwo.entityOne
}

EntityTwo{
  one<-->EntityOne.two
}

… и просто найти связанные объекты с помощью AnEntityOneObj.two.

...