6
votes

I'm constructing a Core Data NSFetchRequest in objective c. In the data model there is an abstract parent entity (which contains 4 basic attributes), and many different child entities that include attributes that aren't in the parent. Some children contain attributes that share the same name and data types.

I am applying the fetchRequest to the parent entity, so that it will search all instances of the child entities to see if a "keypath" exists.

Can I construct a predicate that will only return child entities that contain a particular attribute?

NSPredicate *predicate = [NSPredicate predicateWithFormat:@"%@ IN self.entityAttributes",attribute.name];

Here, attribute is an instance of NSAttributeDescription, and the goal is to search for other entities that have an attribute of a matching name within their list of attributes, but I'm not sure how to format the predicate.

I can clarify further if needed. Thanks!

2

2 Answers

5
votes

Is there a reason why you are inspecting the instances instead of the model? You can easily find out which entity types have a given property

for (NSEntityDescription* entityDescription in [self managedObjectModel]) {
  if ([[entityDescription propertiesByName] objectForKey:@"someProperty"] != nil) {
    // objects of this entity support the property you're looking for
  }
}
1
votes

Interesting question, worthy of some experiment (in the absence of better help).

I tried this predicate on a managed object:

NSPredicate *predicate = [NSPredicate predicateWithFormat:@"entity.attributesByName.allKeys CONTAINS %@", @“nameOfAttrSought”];

But I got this error: “unimplemented SQL generation for predicate.”

Which suggests to me that SQL is not prepared to dig into NSArrays, which is what you get by querying the NSEntityDescription for its attribute names.

If nobody else can come up with a predicate that will do what you want through a direct fetch request, I would suggest this workaround:

Define an entity Namer that has a single string attr named and a to-many relationship members. Create one of these for each of the possible attrs that your target child entities can have. Then give the child entites a to-many relationship to Namer called namers (the inverse of the members relationship). Upon insertion, add the appropriate “namers” to this relationship. Then you could make a fetch predicate like this:

NSPredicate *predicate = [NSPredicate predicateWithFormat:@“ANY namers == %@“, namerSought];
// ("namerSought" is an instance of Namer.)