Reputation: 4033
How do I sort my fetched results by a value that is returned by a method in a category of the entity I'm fetching?
In my category, I sum up several values from the entity's to-many relationship, then divide by the number of objects in the relationship, effectively creating an average that I return in my category method as a float value.
Here is my code:
In the Category.h
- (float)smallPenaltyAvg;
In the Category.m
- (float)smallPenaltyAvg{
float smallPenaltyAvg = 0;
for (Match *mtch in self.matches) {
smallPenaltyAvg += [mtch.penaltySmall floatValue];
}
if ([self.matches count] > 0) {
smallPenaltyAvg = (float)smallPenaltyAvg/(float)[self.matches count];
}
return smallPenaltyAvg;
}
And when I call it in the Core Data Table View Controller class that I created...
NSFetchRequest *poolRequest = [[NSFetchRequest alloc] initWithEntityName:@"Team"];
poolRequest.predicate = [NSPredicate predicateWithFormat:@"regionalIn.name = %@", _regionalToDisplay];
poolRequest.sortDescriptors = @[[NSSortDescriptor sortDescriptorWithKey:@"smallPenaltyAvg" ascending:YES]];
And I have the Category.h
file imported on every file previously mentioned outside of the Category.h
file itself.
It gives me the error of:
Terminating app due to uncaught exception 'NSInvalidArgumentException', reason: 'keypath smallPenaltyAvg not found in entity <NSSQLEntity Team id=5>
Am I not allowed to do this?
If I am, what am I doing wrong?
Upvotes: 0
Views: 267
Reputation: 80265
I do not think this has anything to do with the kind of persistent store.
The trick is to create an appropriate attribute in the managed object model, and mark it as Transient
. Then override the getter of this attribute to do your calculations.
Now your fetch request should work as expected (although there are some caveats with fetched results controllers).
As for the SQLite problem, when you add the SQLite store with
- (NSPersistentStore *)addPersistentStoreWithType:(NSString *)storeType
configuration:(NSString *)configuration
URL:(NSURL *)storeURL
options:(NSDictionary *)options
error:(NSError **)error
just pass NSSQLiteStoreType
as the storeType
. The other options are binary and in-memory, so in this sense this is indeed the "default".
Upvotes: 1
Reputation: 4033
What I did to solve my problem was create a new attribute for every average or sum that I needed in the Team object from all of its Match objects' attributes and then created a method in the TeamCategory file that populated those averages and that method was called every time a Match object was inserted into the Team object. It took a while to do, but it works now. If there is a better solution, I'm still open for suggestions.
Upvotes: 0
Reputation: 6011
This is not possible when using a backing SQLite store.
My suggestion is you persist the average property, and maintain it yourself by overriding the Match
setCategory:
property and making the calculation there for every match added.
Upvotes: 0