views:

1536

answers:

2

Say I have entities organized in a hierarchy with Parent being the root entity and Child being a subclass of Parent. I'd like to setup an NSArrayController to fetch only entities of Parent, but not Child.

If you set the Entity Name of the array controller in Interface Builder to Parent, it fetches all Parent and Child entities. I originally tried setting the array controller's fetch predicate in Interface Builder to:

entity.name == "Parent"

This worked for an XML store, but when I switched to a SQLite store, it no longer worked. I get the following error:

keypath entity.name not found in entity <NSSQLEntity xxx>

As a work around, I am setting up a filter predicate (with the same entity.name predicate as above) in my awakeFromNib to filter only Parent entities. Apparently, that predicate is valid once the entities are in memory, but you can't use it in a SQL-backed fetch predicate.

Is there a way to fetch only Parent entities, but not Child entities using a fetch predicate that works with a SQLite store? It seems wasteful to pull in entities that you're only going to ignore with the filter predicate.

+4  A: 

Leopard introduced the includesSubentities property to NSFetchRequest for exactly this purpose. You'll have to subclass your NSObjectController or NSArrayController to provide the fetch request it will use via its defaultFetchRequest property, or to change the fetch request it uses by overriding its -fetchWithRequest:... method.

Chris Hanson
+2  A: 

I tried using includesSubentities, but it ended up not working completely. It turns out changes to subentities cause the array controller's content to get updated without doing a fetch if you have "automatically prepares content" set to "Yes", thus bypassing the custom fetch predicate. The backtrace shows setContent: being called in response to MOC notifications.

The only way I've found to do this reliably is to use a filter predicate.

Dave Dribin