Группировка результатов основных данных? - PullRequest
2 голосов
/ 28 февраля 2010

Я создаю прототип идеи для iPhone, но нахожусь на перекрестке SQLite и CoreData. Основная причина в том, что я не могу понять, как сделать группировку с основными данными.

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

Я добавил предикат в свой fetchrequest, но он дал мне только одну последнюю добавленную запись, а не самую последнюю добавленную запись для пользователя.

Модель данных довольно проста на данный момент. Используются следующие поля: имя пользователя (строка), сообщение (строка), создано (дата и время)

Короче говоря, возможны ли эти типы запросов с CoreData? Я полагаю, что если SQLite находится под капотом, должен быть какой-то способ сделать это.

Ответы [ 3 ]

16 голосов
/ 28 февраля 2010

Прежде всего, не думайте о Core Data как о другом способе выполнения SQL. SQL не «под капотом» Core Data. Базовые данные имеют дело с объектами. Описания сущностей не являются таблицами, а экземпляры сущностей не являются записями. Программирование с использованием Core Data не имеет ничего общего с SQL, оно просто использует SQL в качестве одного из нескольких возможных типов постоянных хранилищ. Вы не имеете дело с этим напрямую и никогда не должны думать о базовых данных в терминах SQL.

Так лежит безумие.

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

Есть несколько способов выполнить то, что вы хотите в Core Data. Обычно вы создаете выборку с составным предикатом, который будет возвращать все сообщения в определенном диапазоне дат, сделанные конкретным пользователем. Полученные контроллеры результатов особенно удобны для этого.

Самый простой способ - настроить граф объектов следующим образом:

UserEntity
--Attribute username
--Relationship post <-->> PostEntity

PostEntity
--Attribute creationDate
--Attribute content
-- Relationship user <<--> UserEntity

Тогда в вашем классе UserEntity есть метод, подобный так:

- (NSArray *) mostRecentPost{
    NSPredicate *recentPred=[NSPredicate predicateWithFormat:@"creationDate>%@", [NSDate dateWithTimeIntervalSinceNow:-(60*60*24)]];
    NSSet *recentSet=[self.post filteredSetUsingPredicate:recentPred];
    NSSortDescriptor *dateSort=[[NSSortDescriptor alloc] initWithKey:@"creationDate" ascending:NO];
    NSArray *returnArray=[[recentSet allObjects] sortedArrayUsingDescriptors:[NSArray arrayWithObject:dateSort]];
    return returnArray;
}

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

NSArray *arrayForDisplay=[aUserEntityClassInstance mostRecentPost];

Edit:

... я просто передаю каждый блок сообщений данные (контент, creationDate) в разместить сущность? Должен ли я также передать имя пользователя для объекта сообщения? Как пользовательский объект знает, когда создавать новый пользователь?

Позвольте мне псевдо-кодировать это. У вас есть два класса, которые определяют экземпляры userObj и postObj. Когда приходит новое сообщение, вы:

Parse inputPost for a user;
Search existing userObj for that name;
if userObj with name does not exist
    create new userObj;
    set userObj.userName to name;
else 
    return the existing userObj that matches the name;
Parse inputPost for creation date and content;
Search post of chosen userObj;
if an exiting post does not match content or creation date
    create new postObj
    set postObj.creationDate to creation date;
    set postObj,content to content;
    set postObj.user to userObj; // the reciprocal in userObj is created automatically
else // most likely ignore as duplicate

У вас есть отдельные userObj и postObj, потому что, хотя каждый пост уникален, у каждого пользователя может быть много постов.

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

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

1 голос
/ 28 февраля 2010

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

Это отличная технология, но один размер определенно не подходит для всех.

0 голосов
/ 28 февраля 2010

Если 'posts' - это NSSet of User, вы можете получить последнее сообщение с предикатом:

NSDate *lastDate = [userInstance valueForKeyPath:@"@max.date"];

NSSet *resultsTemp = [setOfPosts filteredSetUsingPredicate:[NSPredicate predicateWithFormat:@"fecha==%@", lastDate] ];

Набор resultsTemp будет содержать объект типа Post с самой новой датой.

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