Can a Core Data entity have a relation with itself ?
Something like a Self Join ?
No problems. Just create an entity like Person, then you can create a Manager which is a Person, and Coworkers as Many People. I know this example is contrived, but this is straight forward.
Remember that unlike strings which are stored in the object, the Person in manager and coworkers are just pointers.
Yes, this is what the Apple Documentation says:
A relationship specifies the entity, or the parent entity, of the
objects at the destination. This can be the same as the entity at the
source (a reflexive relationship).
Related
In Core Data I have a House Entity which has a relationship to a Room entity. The Room entity itself has a many-to-many relationship with a Door entity.
Two rooms might share the same door, so here is what I need to know:
Is it possible to have two Room entities with a relationship to the same Door entity. And when updating the properties of the Door entity, it will be the same object and gets updated in both Room entities.
Is it possible to move the Door entity from one relationship to another, without copying it?
You have a many-to-many relationship between Room and Door. This means that those relationships behave as a Set, so you can call myDoor.doors.remove(room), or .insert() to manage the entity. These are reciprocal as well, like all Core Data relationships (see here for further details). Do note your naming scheme is a bit confusing, and for example I'd recommend switching to using myDoor.rooms
would like to ask for the community's suggestions.
I need a persistent store in my iOS app.
I have considered Core Data and SQLite and both are not ideal for the following reasons.
Core Data:
unable to model certain object relationships, such as Object A has a one-to-many relationship with NSString.
//Added:
unable to model a Dictionary(or map) as an attribute for a one-to-one relationship. i.e. Object A has a one-to-one relationship to Object B (and Object B behaves like a dictionary)
SQLite:
poor interface for schema management
no clean and elegant solution for data migration between schema versions
//Added:
unable to model a Dictionary(or map) as an attribute for a one-to-one relationship. i.e. Object A has a one-to-one relationship to Object B (and Object B behaves like a dictionary)
the persistent store has to be able to support search. If anyone can suggest ways to circumvent the problems, that would help too.
Based on your limited description, Core Data would work just fine. Core Data can easily do one to many relationships. No matter what technology that you use, you still need table to table (SQLite) or Object to Object (Core Data) relationships. Nothing is going to give you an Object to String relationship.
You can do Object A to Object B where Object B has only one property which happens to be a string.
I'm struggling with creating a suitable Core Data model for my app. I'm hoping someone here can provide some guidance.
I have two entities -- "Goals" and "Items". The Goals entity contains only a goal description, but any goal may have any number of subgoals, and these may extend multiple levels in a tree structure. Subgoals are to be contained within the same entity, so presumably the Goal entity will contain a pointer to "parent" which will be the parent goal of any subgoal.
There will also be an "Items" entity that contains a couple of text fields and a couple of binary items, and must be linked (ideally, by a unique identifier, perhaps objectID) to the particular goal or subgoal the item(s) are related to.
I am totally fumbling with how to set this model up. I know what attributes need to be in each entity, but the relationships, particularly between goals and "subgoals", has me stumped. I don't seem to be able to turn up any good examples of tree structures in Core Data on the Internet, and even the couple of books I have on Core Data don't seem to address it.
Can anyone here help an old SQL programmer get headed the right direction with these relationships in Core Data? Thanks.
Have you tried creating a one-to-many from Goal to itself, and a one-to-one from Goal to Item? The only thing I would worry about here is circular references.
Also, read Relationships and Fetched Properties in the CoreData Programming Guide.
Here is how it is done:
You set up a to-many relationship from Goal to Item in the model editor. Don't use any ids, foreign keys etc. This is old-fashioned database thinking - you can forget about it. Here we are only dealing with an object graph. The database layer is just an implementation detail for persisting the data.
Make two more relationships in entity Goal to itself: a to-one called parent, a to-many called subGoals. Make them the inverse of each other. Simple!
QED is correct, you can create a to many relationship on goal (call it subgoals) as well as a to-one relationship on goal (call it parentGoal) and set them as inverses to each other.
Then create another to many relationship (call it items) on the goal entity, with the inverse being a to one relationship on the item entity (call it goal). Then you're all set. You don't need to link items with a unique id, just add them to the items relationship.
Also note that if you did want to give items a unique id, do not use the objectID. The objectID should only be used as a temporary id as they are not guaranteed to remain the same. In fact they will change if you ever do a Core Data migration.
One way, though not really great, is to create a another entity, say subGoal, and each goal has one subGoal and each object of subGoal has many goal.
Can a Core Data relationship be its own inverse relationship?
I have a generalized entity that is used to represent different types of objects. Some of these objects have to-many relationships to each other. Do I simply set the relationship as its own inverse, or create a new relationship with the same destination as the inverse?
Since Xcode gives you the option to set a relationship as its own inverse, I'm assuming it's okay, but would just like to make sure. Thanks in advance.
Yes there is no problem with this kind of relationship. You may always have links to objects in the class, even to the object itself.
Just in case you have to delete your objects from ManagedObjectContext you need to consider the deletion rules here https://developer.apple.com/library/mac/#documentation/Cocoa/Conceptual/CoreData/Articles/cdRelationships.html#//apple_ref/doc/uid/TP40001857-SW1.
But really no problem in general with your approach...
I've been studying Core Data quite a bit now, and I've now decided it's time to use it in a new project I'm doing.
Having never use it in a working project I've just come across a few issues I would like to get the communities feedback on.
I'm doing a location based application and I would like to store "outings" in my Core Data model, so for each trip I have some traditional information such as date, distance, description etc... But I also need to save location information which I'll need to plot some points on a map.
So I have a "to" and "from" object per trip, I've created a MapPoint entity with latitude, longitude and location name attributes. On my Trip entity, I've added a "to" and a "from" relationship who's destination is MapPoint.
But what do I do with the inverse property?
Because Xcode seems to give a warning it I leave it as "No inverse".
I needed to create 2 relationships on MapPoint to reference back to the Trip to the "to" and another relationship referencing the "from" relationship of Trip.
Is this correct ? I can't quite understand.
I have a similar issue with a User Entity where this is being used in several other Entities, should I be implementing an inverse relationship back to each Entity which uses User?
To keep Xcode happy it seems I need to create a relationship on User back to Trip, and back to other Entities I'm using such as an Upload, Picture entities etc... it seems to me disturbing to think a Trip has a User object, which would then have prepared to link back to an Upload/Photo... which has nothing to do with that Trip.
If you want to support inverse relationships for your to and from relationships, you can just add appropriate relationships to your MapPoint entity. Call them tripTo and tripFrom, or whatever seems appropriate to you, and set those as the inverse relationships for your to and from relationships, respectively.
As the docs explain, you're not required to model a relationship in both directions, but doing so makes life easier. What happens, for example, when a user is deleted? If you have a number of other entities related to User, then you need some way to figure out which objects were related to that user so that you can update them. If you have inverse relationships, Core Data can automatically update any related objects using the deletion rule (like nullify) that you choose. Without inverse relationships, it's up to you to fix up any related objects.
I'm not entirely familiar with Core Data, but I believe it has a form of entity inheritance.
You could make your MapPoint entity abstract and create a FromMapPoint and a ToMapPoint which inherit their attributes from the MapPoint entity.
Your Trip entity can then have two separate relationships - one to FromMapPoint and one to ToMapPoint with the appropriate inverses.
As I said - I'm no CD expert, so hopefully someone else can come along and validate/shoot-down this suggestion?
With a bit of digging I found that you can set the parent entity through the Data Model Inspector. I created this quick representation of what you've been talking about.
In my experience Core Data doesn't "require" you to have inverse relationships, but not having them leads to mysterious bugs, even if you make sure to keep your object graph consistent manually. At least I think that's what was causing the mysterious bugs.
The SQLite store uses inverse relationships to represent to-many relationships. For a to-many relationship foo from entity A to entity B, I would have thought it would create a separate table "foo" with a column A and a column B, with object ids appearing more than once in column A. Nope. It doesn't represent one-to-many relationships at all, it represents their inverses only, which are to-one relationships. It represents fooInverse as a column in entity B's table, containing object ids that correspond to A-type entities. So you must have an inverse. It seems that in simple cases Core Data can deduce what the inverse should be if you don't define it, and your to-many property works correctly. However in more complicated cases such as the one you describe, it falls over.