CoreData One-to-One Relationship - iphone

In my app, Im using CoreData and I have two entities. VenueInfo and ContactInfo.
In the app, you can add venues, and each venue has ContactInfo. So I've setup a one to one relationship in my model.
So I would imagine, I could simply do the following:
[venue.contact setValue:textField.text forKey:email];
So like so you'd set the email attribute of the contact object which belongs to the venue. However this doesn't work.
Is it possible because the contact object doesn't exist yet?

The line you wrote won't work that way. I assume contact is the relationship name you have in your Venue entity in xCodeModel.
[venue.contact setValue:textField.text forKey:email]; // can't write this way..
Suppose your ContactInfo entity has two fields : phone, email so this way you can go.
and VenueInfo entity has two fields : name.
VenueInfo *venueInfo=[NSEntityDescription insertNewObjectForEntityForName:#"VenueInfo" inManagedObjectContext:self.managedObjectContext];
vanueInfo.name=txtVenueName.text; // venue name entry
ContactInfo *contactInfo=[NSEntityDescription insertNewObjectForEntityForName:#"ContactInfo" inManagedObjectContext:self.managedObjectContext];
contactInfo.phone=txtPhone.text;
contactInfo.email=txtEmail.text;
contactInfo.venue=venueInfo; // I assume venue is the relationship name you give in ContactInfo entity towards Venue entity.
What we did here is we saved phone and email details to ContactInfo entity only and then we just related it with currently selected VenueInfo accessing the relationship we declared in ContactInfo Entity for VenueInfo.
This maybe quite confusing so I'll recommend you to follow a few tutorials which will give you an idea to grasp some basics about core data relationships.

Related

Core Data delete only the relationship link between Many-to-Many - not any objects

This is driving me nuts and I can't find anything where someone else has asked the same question. It can't be an unusual situation.
I have a Student entity and a Classes entity and both are bi-directional
Student<<-->>Classes
A Student can be assigned to many Classes and Classes can have many students
When a Student drops out of a given class, I want to remove the link between the particular student and the class - but without deleting either the student or the class objects.
All my attempts have deleted the student or the class object.
How do I remove the relationship without removing the objects ?
Thank You to Joakim Danielson ! The answer was there... I just wasn't aware... Core Data creates a func for the entity relationship.
As an example
entity Students has a relationship named Classes (destination = Classes entity)
entity Classes has a relationship named Students (destination = Students entity)
Core Data creates a func for each of the entity relationships:
.removeFromClasses()
.removeFromStudents()
these remove the relationship link from each of the respective relationships.
In order to remove the relationship completely, I execute both func - the entity objects both remain but are no longer linked !

how to create a many to many relationships with core data? Swift, xcode

I have 2 entities.
entity 1 - People
entity 2 - books
People entity has a property which is an array of string names of their favorite books.
I need to create a relationship that somehow maps the favorite book of a person to the corresponding book entity object(s).
I am not sure how to do this.
So far I have started by creating a relationship in core data model for people by setting destination to "books" and then for the books entity creating a relationship by setting destination to "people".
I don't see or understand how this will automatically pick out each of the person's favorite books...at the end of the day they are both seperate objects. How will the people class know that for a specific people instance that this, this and this book are that person's favorite?
Person attribute as array of string names of books -- very bad idea!
You need a to-many relationship with the Book entity. That's it.
Person <------------>> Book
Then, to get an array of book titles for a particular person:
(person.books as! Set<Book>).map { $0.title }
The person can have an additional to-one relationship (e.g. called favoriteBook) to one of the books.

CoreData Relationship between entities and attributes

I'm having a little trouble grasping CoreData relationships, i'm note sure which relationship type I should be using between my 2 entities or if my logic is correct.
1) "Person" Entity - attributes such as name, tel, address, country, etc...
2) "CountryList" - attributes such as countryName, countryLat, countryLong, etc..
The CountryList entity is pre populated on first run of the app to include all the countries in the world and their respected data.
Where i'm stuck is do I need a relationship between these two entities?
I will be allowing the user to select a country from the CountryList entity data and wish to store there selection in the country attribute for Person entity.
Do I just take the countryName from CountryList as a string and store it in country from Person? or can I make a relationship between them?
I know a user can only belong to 1 country but a country can have lots of users so is this a one to many relationship? Or is it many to many because lots of users can belong to a country but a country can have loads of users? Confused!
Could someone please enlighten me on this and point me in the right direction in what i should be doing in xcode.
Many Thanks in Advance
Matt
EDIT: Is this correct?
I have made the changes to Entity names etc and think I now have the relationship set correctly.
EDIT 2: Removed country attribute and renamed relationships
Firstly, your "CountryList" entity should be called "Country", since it represents only one country. The fact that you have many of those countries has nothing to do with its name.
After that, it seems just natural to use a relationship, one "Person" has one "Country", but one country can have many persons. Therefore, one-to-many relationship. Using a relationship will simplify many operations you might want to perform (i.e. access all the country information of one person, or get a list of all persons being in one particular country).
Oh, and this might help you understand relationships a bit better: There are no "many-to-many" relationships in CoreData per se. You always define a relation from a source to a target. So if you define a relation from Country to Person, this will be a one-to-many relationship. One country, many persons. You can then define a relationship from Person to Country, which would be a one-to-one relationship. One person, one country. If you defined this as an one-to-many relationship, you would end up with a de facto many-to-many relationship (because on person can have many countries and one country can have many persons). It's not as complex as it appears.
Now, after you've defined your two relationships, you can set them as each others "Inverse Relationship". Do it for one of the relationships, the other one will be set automatically. After you did that, CoreData will for example update a Person's country when you add the person to the country's list.
See https://developer.apple.com/library/mac/#documentation/Cocoa/Conceptual/CoreData/Articles/cdRelationships.html for further information.
CountryList should just be Country
Then you set a 'many to one' relationship between Person.county and Country
You are using Core Data so you must define relationship between Person and Country if you want to fetch person's country from database.
And in this relationship you may take one to one relationship. As One person will belong to one country only. Of Course a country will have many person but unless you want to show all people related to particular country you do not need one to many relationship..
In case you want to implement one to many relationship this tutorial link maybe helpful to you for understanding one to many relationship..
http://www.theappcodeblog.com/2011/09/29/iphone-app-development-tutorial-core-data-part-2-one-to-many-relationship/

Cascade eager-loading problem

Supose I have following entities created from database tables:
Person
Student
Student include Person as navigation property.
Person has navigation property Country to connect lookup table Country.
In Student metadata, I do put [Include] for navigation property Person.
In Person metadata, I do put [Include] for navigation property Country.
When loading student data, I want to eager loading like to include Person and Country data:
this.ObjectContext.Students.Include("Person").Include("Country");
This was working fine when I use previous version of ASP.NET Data Ria Service. Now when it is changed to WCF Ria Service, above way not working any more.
System give me the error said Country is not a navigation property of Student.
How to resolve this problem?
The error is correct.
Include is on the ObjectQuery<T> you are querying, in this case "Students".
Country is a navigational property of Person, not Student.
Change your code to this:
this.ObjectContext.Students.Include("Person").Include("Person.Country");
Or simply:
this.ObjectContext.Students.Include("Person.Country");
As EF will automatically include "Person" based on the nested include.
You need to remember that Include returns an ObjectQuery<T> based on the ObjectQuery<T> it was invoked upon.
So just because your doing Students.Include("Person"), that doesn't mean at that point, the variable is ObjectQuery<Person> - the variable is still ObjectQuery<Student>.

core data iphone readonly relation

I have situation where I dont want to add records to the relation table.
For example :
I have "TRIPS" entity and it has attribute for "LOCATION_ID", I am filling it when user creates a new TRIP and select a LOCATION from the LOCATIONS entity
In "LOCATIONS" entity I am allowing user to create locations and I am assigning a unique ID to each location.data will not be repeated here.
Is there any way to link the LOCATION_ID into LOCATIONS entity ,so when ever I access a trip(NSManagedObject) it automatically get LOCATIONS entity record (Object) ?
I mean automatically (Manually I can do that)
Thanks,
Raghu
If I understand correctly your question, you simply need to model differently your entities in the Core Data model, as follows. In your TRIPS entity, add LOCATIONS as a relationship, not as a property as you currently do. The relationship may either be to-one or to-many from TRIPS to LOCATIONS, depending on the constraints you want to enforce in your application, and to-one from LOCATIONS to TRIPS.
Once you do this, when you fetch objects from the TRIPS entity, they will also contain a LOCATIONS object (if you decide to use a to-one relationships) or a set of LOCATIONS objects (if you decide for the to-many relationship).