Where can I find a good example of a Core Data to-many relationship?

23,672

Solution 1

People are often confused by to-many relationships because one entity represents the relationship as a set while the other represents it as a single object. Take the following entities:

EntityA{
    name:string
    bees<-->>EntityB.a
}

EntityB{
    name:string
    a<<-->EntityA.bees
}

In EntityA, the relationship bees is a set because there maybe many EntityB objects in the relationship. So, using Key-Value coding, you would have to access the relationship using a mutableSetForKey: expanding everything out to see the detail would like so:

NSMutableSet *muteSet=[anEntityAObj mutableSetValueForKey:@"bees"];
[muteSet addObject:aNewBObj];
[anEntityAObj setValueForKey:@"bees"];

...or more compactly:

[[anEntityAObj mutableSetValueForKey:@"bees"] addObject:aNewBObj];

If you set from the EntityB side, however, you are only adding a single object so you can just use setValueForKey: directly like so:

[anEntityBObj setValueForKey:anEntityAObj];

That's if you use generic NSManagedObject instances to represent your entities. If you create custom subclasses then you have properties and methods to do the setting for you:

[anEntityAObj addBeesObject:anEntityBObj];
anEntityBObj.a=anEntityAObj;

Remember as well that with managed objects, setting one side of a relationship defined as reciprocal automatically set the other side as well and removing works the same way.

Update

Lets say i've got 2 entities -- Person:with "name" attribute -- Times:with "time" attribute -- i would want to set multiple times for each name, but how to I tell it which name i would like to add the specific times to?

You don't create relationships with attributes, in this case name but rather with an object, in this case an instances of the Person entity/class. Each individual Person object is completely separate from all other Person objects even if they have the same value in their name attribute.

You must obtain a reference to any particular Parent object. If you have just inserted a new Parent object then you already have a reference to it. If it is already been inserted/persisted, then you create a fetch with a predicate that will return the proper object. Once you have the correct Parent object you then just add the Time objects to the relationship.

So, if your entity looks like this pseudo-code:

Parent{
    name:string
    times<-->>Time.parent
}

Time{
    theTime:date
    parent<<-->Parent.times
}

... and you are using generic NSManagedObjects to instatiate you entities, you set the relationship between an existing Parent object and new Time object something like this:

NSManagedObject *existingParent= //... results of a fetch
    NSManagedObject *newTime=[NSEntityDescription insertNewObjectForEntityForName:@"Time" inManagedObjectContext:self.moc];
    [newTime setValue:[NSDate date] forKey:@"theTime"];
    [newTime setValue:existingParent forKey:@"parent"];

Note that if you set the relationship from the Time object's side, you can use setValue:ForKey: because from the Time object's perspective the relationship is just one object to one object.

It is really quite simple once you start thinking in objects instead of databases. Each object you insert in a context is unique even if it shares attributes with other objects of the same entity/class. That is why you can set a relationship between specific objects without necessarily worrying about the values stored in their attributes.

Solution 2

Here is an example of a one-to-many relationship, as long as you have set up the relationships so they have an inverse they are quite easy to manage. at the end, Entity1's chilren attribute will contain entity2 and entity3

Entity1 *entity1=[NSEntityDescription insertNewObjectForEntityForName:@"Entity1" inManagedObjectContext:self.managedObjectContext];
Entity2 *entity2=[NSEntityDescription insertNewObjectForEntityForName:@"Entity2" inManagedObjectContext:self.managedObjectContext];
Entity2 *entity3=[NSEntityDescription insertNewObjectForEntityForName:@"Entity2" inManagedObjectContext:self.managedObjectContext];

[entity2 setParentEntity:entity1];
[entity3 setParentEntity:entity1];
NSError *error;
[[self managedObjectContext]save:&error];

NSSet *set=[entity1 children];

enter image description here

Solution 3

I am currently using this ebook and its very well written: It explains and shows how to create datamodels and there are also there are code examples..

"Pro Core Data for iOS" http://apress.com/book/view/1430233559

Hope it helps

Solution 4

Download the iPhoneCoreDataRecipes sample code. It's a full working demo of Core Data and an excellent way to get familiarized with the concepts.

Solution 5

Get Marcus Zarra's book "Core Data" (you can buy a PDF rather than paper for instant gratification...) It too presents examples in Mac OS X but it goes a lot further than just getting started. You will find out useful things like versioning, transition rules, optimization. This book saved one of my projects from being late & slow!

Share:
23,672

Related videos on Youtube

James Dunay
Author by

James Dunay

Flash Developer / Objective C

Updated on June 29, 2020

Comments

  • James Dunay
    James Dunay over 3 years

    Does anyone have a tutorial or source code that shows a to-many relationship being used, where the user add elements in on the fly? I would just like to have a look because reading about it hasnt been much help.

  • James Dunay
    James Dunay about 13 years
    Lets say i've got 2 entities -- Person:with "name" attribute -- Times:with "time" attribute -- i would want to set multiple times for each name, but how to I tell it which name i would like to add the specific times to?
  • James Dunay
    James Dunay about 13 years
    Also could you give an example of what aNewBObj might be?
  • James Dunay
    James Dunay about 13 years
    What if my fetched object has the same name as another? how can I tell it to fetch only exactly the one that I would want?
  • TechZen
    TechZen about 13 years
    That's part of of data model design. You have to include enough information in the attributes to distinguish one object from another. After all, real-objects, events or conditions have a lot of information that distinguishes them and you need to make sure capture that in your data model.

Related