Core data many-to-many relationship - Predicate question

12,638

Solution 1

This seems to work OK:

NSPredicate *predicate = [NSPredicate predicateWithFormat:@"(ANY lists == %@)", myList];

Where myList is an actual List entity.

Solution 2

Given a data model like:

List <<——>> Patient,

you can find all Patient instances that belong to a list with a particular name with a fetch request on the Patient entity using a predicate like:

[NSPredicate predicateWithFormat:@"ANY lists.name LIKE[cd] %@", listName]

assuming listName is an NSString instance with the list name you want. LIKE[cd] does a case-insensitive and diacritic-insensitive comparison.

Solution 3

It sounds like your data model is this:

List <<-->> Patient

I would think that if you know the particular list name, then you know the particular list object. If so, you can just grab the patients using the to-many relationship from List to Patient--it is a set of patient objects. For example, if the relationship from List to Patient is named "patients":

NSSet *patientSet = listObject.patients;

Note: this requires that you create subclasses for your managed objects so you can access the attributes and relationships as properties on your objects.

If you only know the list name for some reason, and you are fetching Patient objects, then you can create a predicate using the to-many relationship from Patient to List (assume it's named "lists" and the list's name in a string named "listName"):

NSPredicate *pred = [NSPredicate predicateWithFormat:@"ANY lists.name == %@",listName];

Solution 4

Ten years later, some more info !

Just some more info on the fantastic @GarryPettet answer,

Say you have entity CD_Person and aPerson is one of those. IE:

var aPerson: CDPerson

Say you have an entity CD_Pet

CD_Person has a relationship .pets which is a one-to-many CD_Pet

So just to be clear,

aPerson.pets

is indeed a Set of CD_Pet entities.

Almost certainly you'll have an id field which comes from your data source.

(Aside, .id must be an Int64 in your core data entity, even if it's a smaller int in your source data)

Two ways to go!

BOTH this

let p = NSPredicate(format: "(ANY pets == %@)", aPerson )

AND this

let p = NSPredicate(format: "(ANY pets.id == %lld)", aPerson.id)

... work perfectly, both are possibilities.

So there's two ways to go!

(PS: Don't forget the lld .. @ won't work for Int64!)

Both work fine in the common situation where you have a "many-to-many" relationship.

Share:
12,638

Related videos on Youtube

Garry Pettet
Author by

Garry Pettet

I'm a former UK radiologist who now works full time as a web, desktop and iOS developer.

Updated on April 14, 2022

Comments

  • Garry Pettet
    Garry Pettet about 2 years

    In my Core Data model I have two entities: List and Patient. List has an attribute called 'name'.

    A List can have any number of Patients and each Patient can belong to any number of different lists. I have therefore set a relationship on List called 'patients' that has an inverse to-many relationship to Patient AND a relationship on Patient called 'lists' that has a to-many relationship to List.

    What I'm struggling to figure out is how to create a Predicate that will select all Patients that belong to a particular List name.

    How would I go about this? I have never used relationships before in Core Data.

  • vond
    vond over 14 years
    In the first example (which is correct as usual from gerry3), you can access it via KVC without having to subclass it using NSSet *patientSet = [listObject valueForKey:@"patients"];
  • Garry Pettet
    Garry Pettet about 14 years
    I have the List entity in memory and I pass it to a UITableViewController subclass. How would I construct a fetch request to grab all patients from that list entity? I'm trying to use a NSFetchedResultsController and a list's name is not unique (so constructing a predicate based on name alone could cause errors).
  • Nick
    Nick over 13 years
    But how do you "convert" that into Fetched results controller? I also have the same question and I do have the reference to the "list" object, but I would like to have a fetched results controller that shows "list.patients"
  • Nick
    Nick over 13 years
    Actually nevermind, the answer from @Garry below is what I was looking for