Creating Core Data relationships after filling up entities with data - iphone

Say you have a couple of Core Data entities .. Student and Exam. These two are initially filled with data from two xml files downloaded from the web.
Now, Students and Exams are separate things... initially there are no connections between them. But after filling out these two entities, I might want to connect certain students to certain exams. Or I might want make all students take a particular exam. But I still want to be able to treat Exams as independent things, which might have no students connected.
I'm unsure how to do this with Core Data. In the data model, you either have a relationship or yo don't. Should I have two different entities for Exam... one for independent exams, and one connected to the student which can be built up from the other Exam enitity?

No, you should not make two entity types.
Just because you have a relationship between two kinds of entities doesn't mean you can't create an object where that relationship is nil.
So, assuming you have a many-to-many relationship between Student and Exam, you might create a new exam by doing something like:
Exam *newExam = [NSEntityDescription
insertNewObjectForEntityForName:#"Exam"
inManagedObjectContext:context];
newExam.course = #"CS 101";
newExam.description = #"Midterm";
You might then later establish a relationship between a student and that exam like:
[newExam.students addObject:aStudent];
(where students is the name of the relationship between Exam and Student

I think you should have a relationship between the two entities (exam and student) but mark it as optional.

Related

How do I read bridge entities in ERDs?

First time posting here as I was told to seek help from this community if I was ever stuck!!
I was recently introduced to databases this semester and I have a hard time grasping the bridge entity that is meant to erase the many-to-many relationships.
The classic example would be the relationship between STUDENT and CLASS;
where STUDENT can be in many CLASSES and a CLASS can have many STUDENTS.
The M-M relationship is fixed by introducing the ENROLL entity. Here we would read: a STUDENT can ENROLL in many CLASSES, and a CLASS may have many STUDENTS ENROLLED in it, however each STUDENT can be ENROLLED in a CLASS only once.
In my case, I tried to fix a M-M relationship issue between PRODUCT and RAW MATERIAL for a pharmaceutical company by introducing an INGREDIENT entity, which looks like this:
RAW MATERIAL 1----M INGREDIENT M----1 PRODUCT
I am not sure if the bridge works out because I have trouble interpreting it like the STUDENT-CLASS example above.
How would you interpret this?
The concept of "bridge" or "associative" entities came from network data modeling and was a way of handling many-to-many binary as well as ternary and higher relationships. Network data modeling is a simple physical data model based on representing entities as records and relationships as references/pointers.
Since the 1970s, the relational model of data has been developed which uses relations (tables) to record relationships between sets of values (which represent business entities, measurements and labels), allowing for the direct representation of many-to-many relationships and ternary and higher relationships.
The entity-relationship model was an attempt to provide more conceptual structure on top of the relational model, by distinguishing entity relations from relationship relations.
My point with the history is that in modern data modeling, we no longer resolve or erase many-to-many (or ternary or higher) relationships (unless you're using an object-relational mapper or framework based on the network data model). Tables with composite keys, consisting of two or more entity keys, directly represent relationships, and allow us to handle attributes on relationships as well, another feature missing from network data modeling.
In your case, it may be useful to add a Quantity attribute on your Ingredient relationship. The interpretation here is that Raw material refers to a type of material rather than a specific piece or selection of raw material. Students have identity, raw materials generally don't.
Note that pharmaceutical companies may well track specific batches of raw materials.

Implement multiple relationship using core data

Here above shows the ER-Diagram.
It's easy to implement to-many binary relationship using core data. But it confuse me how to implement this kind of multiple relationship.
Hope that someone could give a hand.
I am not sure if I understood your problem correctly, but wouldn't two
one-to-many relationships (from Course to TA and from Student to TA) describe
your model? Each TA has exactly one Student and one Course, but each Student and
each Course can be related to many TAs.

Core Data Entity with several parent relationships

Let's say there is an entity called Product, which is connected to Shop (a shop has several products). However, there is also an entity called SpecialWebOffers, which also has a number of Products (which are not in any Shop).
How do I connect both Shop and SpecialOffers to Product. Is it OK to have two relationships in Product - one to Shop and one to SpecialWebOffers?
It's very common for an entity to have multiple relationships. If I am understanding your question correctly then the answer is yes.

Saving a One To Many Relationship in CoreData

I have created a core data model that has two entities which have a one to many relationship. The entities are Exams and Questions. An Exam can have many questions.
What is the best way to save the Questions entities so they would be associated with the specific Exam?
The flow I want it to have is to start a new exam with an exam name, then add questions, then close out the exam with the questions count and save it to the persistent store.
After creating a Question object, just set its .exam property (provided that's the name of the inverse relationship to e.g. Exam.questions) to the containing exam object. If you need to order the questions, have a look at ordered relationships (available since Lion / iOS 5) or this or this.

Copying entities in Core Data

I have a couple of Core Data entities... Student and Exam.
Now, the Exams is initially just one object per exam - Maths Exam 3, English Exam 2 etc.
There is a relationship between Students and Exams in my data model (a student can have several exams). But initially, the Exams are just floating free, and not attached to any students.
How would I make a copy of one of the exams and attach it to a student?
If I do something like:
[student addExamsObject:examObject];
...then I think it simply references the original exam to the student, rather than making a copy.
I need a copy because the Exam has a boolean 'hasTaken', which is YES when the student has taken the exam. But if I set that now, it will make it seem like all the students with that exam have taken it.
Clarification: I would rather not restructure my model. The data is taken from a couple of xml files, one each for Students and Exams, which are parsed into the Core Data store. For instance, an Exam object might look like this:
name:Maths 5
class-id:12
year-id:4
student-id:0
..with a Student object looking like
name: Dave
class-id:12
year=id:4
student-id:222
Various rules are meant to guide which exams get attached to which students... for instance if all the Exam's ids are 0 then all students take the exam. If class-id and year-id match, and student-id is 0, then the Exam gets added to students with the same class and year. If the student-ids match, then just that student takes the Exam. etc etc.
I cannot change the way the xml is outputted from the server.
Another issue is that Exam has too-many relationship to a Question entity... in other words, the questions in the Exam. And I have to store answers to the questions that each student gives in an exam.
Edit: I wish people would try to answer my question rather than tell me to restructure my whole program. There are reasons why the data model has been structured like it is.
Edit2: Maybe I will have restructure....
Exam shouldn't have a hasTaken property. Think about it in the real world. An Exam would not know about who has taken it because many people could have taken it. The instance of taking an exam, then, should be a first-class concept in your model.
Consider this:
Exam has many TakenExams, TakenExams belongs to Student http://yuml.me/6627495d
Now the concept of taking an exam is a real object, you can then model assocation metadata as well, such as dateTaken, score, and so on.
Also remember that Core Data expects you to have all of your inverse associations set up as well.
You don't usually copy an entity. (I'm not sure what happens if you call copy on an NSManagedObject... it's not explained in the documentation, as far as I know. Experts can correct me. )
Just create another entity, or write a method which does just that.
I think another way is to make many-to-many relationships between Exam and Student:
create relationships in Exam called studentsToTakeThisExam and studentsWhoTookThisExam.
create relationships in Student called examsToTake and examsAlreadyTaken.
and set up the inverse relationships accordingly.
I would not argue (as You requested) if your modeling is correct or not. The procedure to copy an entity is, in general, quite complex, owing to the fact that, besides attributes, you also need to deal with the entity's relationships and copy them. I can not post here a huge amount of source code showing how to accomplish this, however, I can point you to a book where this issue is described in detail, with all of the source code you need. The book is the one from Marcus Zarra, "Core Data Appleā€™s API for Persisting Data on Mac OS X" by "The Pragmatic Programmers".
You really don't want to copy an Exam in this situation. You'd end up with lots of identically named Exams which didn't have a relationship with each other, and then you'd be forced to group them together (if you wanted to) by their name.
I'd recommend a new entity (perhaps "ExamSitting"?) which represents a Student sitting an Exam. You could then a to-many from Student to ExamSitting, and a to-many from Exam to ExamSitting. This enables you to have as many attributes on the ExamSitting as you like then (hasTaken, grade and so on).
Edit
Okay, given your clarification, I have a point or two to add (although they may not be what you're looking for). I understand that you're loading from files with a particular structure, but that doesn't necessarily have to dictate your structure.
With the XML files laid out as you now describe, I would still use an Exam - Student - ExamSitting model. If I were to implement it, I'd load all the Students, and then, for each record in the Exams file, I'd create one Exam object, and then a number of ExamSitting objects, one for each Student that fits the criteria defined in the record. As I mention above, this enables you to store more information about each event, such as mark, takenDate and so on.
If you're sure there's no requirement to be able to store additional information at this granularity, you could just create a to-many relationship studentsTakingExam. This could be populated as you load each exam record by querying the loaded Student entities.