问题
Assume two ManagedObject backed by Sqlite:
1.) A User
which has two properties, firstname
and lastname
and a virtual (transient) property fullname
which is read-only.
@interface User : NSManagedObject
...
@property NSString *firstname;
@property NSString *lastname;
@property (readonly) NSString *fullname;
@end
@implementation User
...
- (NSString*)fullname
{
return [NSString stringWithFormat:@"%@ %@", self.firstname, self.lastname];
}
@end
2.) A Message
which has besides several other properties a relationship to exactly one User stored in sender
property.
@interface Message : NSManagedObject
@property User *sender;
@end
I want to fetch all instances of Message with a certain sender's fullname. This is the NSPredicate I am constructing:
[NSPredicate predicateWithFormat:@"sender.fullname CONTAINS[cd] %@", @"Searched Name"]]
Unfortunately, I am getting an NSInvalidArgumentException
once I start searching:
*** Terminating app due to uncaught exception 'NSInvalidArgumentException', reason: 'unimplemented SQL generation for predicate : (sender.fullname CONTAINS[cd] "S")'
回答1:
You can't use transient properties in a fetch request predicate, this is because the data you're trying to use doesn't exist in the SQLite database.
You need to rewrite the predicate to use only firstname
and last name
.
You may want to do that with BEGINSWITH
and ENDSWITH
and then you may also want to run a second filter once you have the results of the fetch to ensure you don't have any false positives in the result set.
Alternatively you can make the full name non-transient and then it can be used in the predicate. In this case you would implement custom accessor methods to ensure that any update also applies to the full name.
来源:https://stackoverflow.com/questions/34592473/how-to-use-nspredicate-with-chained-virtual-property