How can you reference child entity name in a predicate for a fetch request of the parent entity?
Asked Answered
B

3

8

I have the need to create a complex predicate for an abstract base object. I want to have separate predicate queries for different inheriting entities and key off the sub-entity type, the example below is what I would like to do, however, I have not been able to find a way to reference the entity name or type in the predicate.

NSFetchRequest *request = [[NSFetchRequest alloc] init];
request.entity = [NSEntityDescription entityForName:@"MyCommonObjectBase" inManagedObjectContext:myContext];

NSPredicate *subclassAPredicate = [NSPredicate predicateWithFormat:@"someValue > %@ && entityName = %@", 100, @"SubclassA"];
NSPredicate *subclassBPredicate = [NSPredicate predicateWithFormat:@"someValue < %@ && entityName = %@", 50, @"SubclassB"];

request.predicate = [NSCompoundPredicate orPredicateWithSubpredicates:[NSArray arrayWithObjects:subclassAPredicate, subclassBPredicate, nil]];
Baggywrinkle answered 16/10, 2009 at 17:24 Comment(0)
B
14

I got a response from Apple at http://bugreport.apple.com problem number 7318897:

entity.name is not a modeled property, so it's not legal. it works by accident on the binary store. The correct way to fetch subentities is to do so on the NSFetchRequest and use either setIncludesSubentities or not.

So it seems the proper solution is to have separate fetch requests and to merge the result sets after execution.

Baggywrinkle answered 18/11, 2009 at 6:22 Comment(1)
so what you are saying is, my problem doesnt have a solution rather than to fetch the result first and then apply the rest predicates on the result in hand ? #11935263Overuse
S
3

A shot in the dark here, but what about using the className value in the predicate?

NSPredicate *subclassAPredicate = [NSPredicate predicateWithFormat:@"someValue > %d AND child.className = %@", 100, @"SubclassA"];

(Notice that you had an error in your predicate format. You were using %@ to try and substitute in an integer value (100). %@ is only used for objects. Use %d (or some other flavor) for primitives)

EDIT Found it!

You'll want to do this:

NSPredice * p = [NSPredicate predicateWithFormat:@"entity.name = %@", @"SubclassA"];

I just tested this on one of my apps and it seems to work.

-Another edit-

Here's the test that I ran, which seemed to work:

NSManagedObjectContext * c = [self managedObjectContext];
NSFetchRequest * f = [[NSFetchRequest alloc] init];
[f setEntity:[NSEntityDescription entityForName:@"AbstractFolder" inManagedObjectContext:c]];
[f setPredicate:[NSPredicate predicateWithFormat:@"entity.name = %@", @"DefaultFolder"]];
NSError * e = nil;
NSArray * a = [c executeFetchRequest:f error:&e];
[f release];
NSLog(@"%@", a);

When I run that, a logs two NSManagedObjects, both of the @"DefaultFolder" variety (which is what I was expecting). (AbstractFolder is an abstract entity. One of the child entities that inherits from it is a DefaultFolder)

Salim answered 16/10, 2009 at 17:32 Comment(7)
I'll give that a shot, thanks. Yeah, that's a typo from generalizing some production code for the sake of illustration.Baggywrinkle
No luck, className is not a valid keypath. Also, I'm looking for the entity name of self not a child entity just to clarify.Baggywrinkle
I don't see the same result, when I add that I still get an error with message "keypath entity.name not found in entity".Baggywrinkle
Did you do this in an iPhone app or Mac app? I wonder if there is a difference in the Core Data implementation.Baggywrinkle
@Greg - I just tried it w/ an iPhone app and found something curious. It will work if your store type is NSBinaryStoreType, but not if it's NSSQLiteStoreType. My code above was running on an NSXMLStoreType. I'll keep looking for a way to do it on a SQLiteStoreType.Salim
I have submitted a bug report to Apple on this, hopefully they can fix it at some point.Baggywrinkle
entity.name didn't work in iOS for me either. Keypath not found for entity.Transcendentalistic
A
-1

The only way of associating a predicate with an entity I know of like is this:

NSPredicate * predicate = [NSPredicate predicateWithFormat: @"(%K == %@)", fieldName, fieldValue, nil];
NSFetchRequest *request = [[[NSFetchRequest alloc] init] autorelease];
[request setEntity:[NSEntityDescription entityForName:entityName inManagedObjectContext:managedObjectContext]];
[request setPredicate:predicate];

Maybe you were referring to the field name?

Edit: the entity is associated with the request, not with the predicate.

Administrator answered 19/10, 2009 at 13:46 Comment(0)

© 2022 - 2024 — McMap. All rights reserved.