问题
I have a have a number of calendars, which each have a number of events. I would like to find all the events for a calendar where date > x.
My method signature looks like this
-(NSArray*)eventsForCalender:(Calendar*)calender StartDate:(NSDate*)start endDate:(NSDate*)endDate;
I added an Event to a calender like this, but I don't have a clue how to go about to construct an NSPredicate for the query. Any help appreciated
-(Event*)newEventforCalender:(Calendar*)calender
{
Event * newEvent = (Event*)[NSEntityDescription insertNewObjectForEntityForName:@"Event" inManagedObjectContext:app.managedObjectContext];
NSMutableSet * eventsArray = [calender mutableSetValueForKey:@"Events"];
[eventsArray addObject:newEvent];
[app.managedObjectContext processPendingChanges];
return newEvent;
}
alt text http://img4.imageshack.us/img4/5218/screenshot20091120at140.png
I changed the relationship name to "events" and tried the following
....
NSEntityDescription * entity = [NSEntityDescription entityForName:@"Calendar" inManagedObjectContext:app.managedObjectContext];
[request setEntity:entity];
NSPredicate * predictate = nil;
predictate = [NSPredicate predicateWithFormat:@"(name == %@) AND (Event.start > '%@') AND (Event.finish < '%@')", calender.name, start, endDate, nil];
[request setPredicate:predictate];
...
However i'm getting an exception
Terminating app due to uncaught exception 'NSUnknownKeyException', reason: '[ valueForUndefinedKey:]: this class is not key value coding-compliant for the key Event.'
回答1:
Some thoughts:
- In your model, is
newRelationship
really calledcalendar
? - You want to rename
Events
toevents
to follow naming conventions (entities likeEvent
andCalendar
are capitalized, while attributes likediscipline
and relationships likeevents
are lowercase) - Wire up the
calendar
andevents
relationships in both directions
That said and done, you could use a predicate like:
- (NSArray *) eventsForCalendar:(Calendar *)calendar startDate:(NSDate *)startDate endDate:(NSDate *)endDate {
NSPredicate *_predicate;
NSString *_predicateStr;
NSSet *_calendarQueryResults;
_predicateStr = [NSString stringWithFormat:@"(name like '%@') AND (event.start > '%@') AND (event.finish < '%@')", calendar.name, startDate, endDate];
_predicate = [NSPredicate predicateWithFormat:_predicateStr];
_calendarQueryResults = [_managedObjectContext fetchObjectsForEntityName:@"Calendar" withPredicate:_predicate];
return [_calendarQueryResults allObjects];
}
This will work if the calendar name is sufficient for uniquely identifying an individual calendar. If you have two calendars with the same name, you would have to add an additional search criterium, like @"(category like '%@') ... ", calendar.category, ...
You can also use the object ID:
_predicateStr = [NSString stringWithFormat:@"(SELF == %@) AND (event.start > '%@') AND (event.finish < '%@')", calendar, startDate, endDate];
A good reference for NSPredicate
programming is Apple's aptly named NSPredicate Programming Guide.
来源:https://stackoverflow.com/questions/1770646/one-to-many-relationships-iphone-nspredicate-core-data-query