CoreData - select specific entry from one to many relationship
Damn you short titles! :p
Basically I have an entity named "threads" and I have an entity named "messages". I have a one to many relationship from threads ->> messages (and a one to one inverse relationship).
What I need to do is get all the records from the threads entity and for each one I need to get the message with the latest timestamp (this is just an int in the "lastUpdated" attribute, so the highest number I guess will suffice).
I'm not sure what other information you may want, here is a screenshot of my entities:
I'm sure there must be a better w开发者_如何学编程ay than iterating through all the records and comparing the threadIds?
Thank you.
Once you have the individual Thread objects, you just need to do a sort on the Messages objects and take the topmost Message object.
The easiest solution would be to create a method in the Thread class like this:
- (Messages *) lastUpdatedMessage{
NSSortDescriptor *sort=[NSSortDescriptor sortDescriptorWithKey:@"lastUpdated" ascending:NO];
NSArray *sortedMessages=[self.messagesInThread sortedArrayUsingDescriptors:[NSArray arrayWithObject:sort]];
return [sortedMessages objectAtIndex:0];
}
Then all you have to do is ask each Thread object for its lastUpdatedMessage.
A more complex but more efficient solution would be to create an intermediate linking entity that would link one Message object to one Thread object and set that link object as the Message objects update. So:
MessageThreadLink{
message<--(required)-->Message.lastUpdateLink
thread<--(required)-->Thread.lastUpdatedMessage
}
Whenever a Message object updated, it would tell it's related Thread object to delete the existing link object and create another one pointing to it. You would probably put that code in a custom setter for the lastUpdated property.
With this method you just have to ask each thread for its lastUpdatedMessage and it appears automatically without a lot of searching and sorting.
Can't you just use NSPredicate to perform a filter on the data and attributes values you need like you'd perform a query on a simple database? (or maybe I'm missing a point)
So your lastUpdated attribute is an int and not NSDate? If so, does it have to be an int and do you do anything else with the data stored in that attribute?
I was thinking you could possibly use a BOOL attribute that marks a message as lastUpdated == YES and then all you need to do is fetch your Message entities that match that predicate. You will still be able to access the thread entity via the one-to-one relationship so you can fetch and display that data the way you want.
[edit] As a side note, I think you might find it more intuitive to use singular words to name your entities as each Thread entity contains one thread and each message entity contains one message.
OR Option 2
change your lastUpdated attribute to be NSDate and set the default value for NOW so whenever the entity is created it will pre-populate with the current date/time.
Then for each thread you have saved, pull the associated messages, sort them by NSDate and pick the first object on the array if ASCENDING == NO or the last object if ASCENDING == YES.
精彩评论