If I delete a CoreData record from an entity, does that also delete the relationship that record had with another record in another entity?
It depends on the Delete Rule that you have enabled for the relationship. The Core Data Programming Guide documents these (extracted below). Have a look in the inspector to see which option you have set for your relationships. If you have a specific data model which you want comment on you should edit your question to be more specific.
Deny
If there is at least one object at the relationship destination, then the source object cannot be deleted. For example, if you want to remove a department, you must ensure that all the employees in that department are first transferred elsewhere (or fired!) otherwise the department cannot be deleted.
Nullify
Set the inverse relationship for objects at the destination to null. For example, if you delete a department, set the department for all the current members to null. This only makes sense if the department relationship for an employee is optional, or if you ensure that you set a new department for each of the employees before the next save operation.
Cascade
Delete the objects at the destination of the relationship.
For example, if you delete a department, fire all the employees in that department at the same time.
No Action
Do nothing to the object at the destination of the relationship. For example, if you delete a department, leave all the employees as they are, even if they still believe they belong to that department.
Related
Let say I have core data and three entity inside : Department, Employee, Inventory
So every department could have more employees, and every employee could have more items that is record as inventory.
Department <--->> Employee <---->> Inventory
Now lay say, that we have method (service,...) that return new list of employee for department.(Let assume that this could happened quickly.)
The logic is that we delete all instance of Employee of specific Department, and then insert new ones.
The best way would be (for me), that I could do something like that :
let employees_local = myDepartment.employees
if let employees = employees_local {
myDepartment.removeEmployees(employees)
}
But this (in my understanding) only remove relationship between those object and don't delete all those objects.
I know for solutions where you delete all entity of a kind (delete all Employees)
like : this post, or this one.
I even know that I can do a batch delete from ios 9 on. Like here
My question is, is there a faster/ better way to do this. Shouldn't be there a way, that you tell core data to delete all object that have no relationship on parent?
Using the example you looked at above linked as "this one".
If you use a predicate that filters the Employees by checking the relationship to Department is nil, that'd return just the data items you want. Then I suggest you could delete all of them.
Suppose I have two entity named Book and Publisher
1. Book has attribute :- writer, title.
2. Publisher has attribute :- name, type
I set a relationship :- Publisher to Book ( one to many and set it as inverse relation)
With relationship selected I can see in DataModal inspector a row called Delete Rule with three options 1. Nullify 2. Cascade 3. Deny
What these are and I want to delete Publisher entity only if I delete the last Book
Thank You in advance.
I'm just a beginner
:)
The docs do a good job explaining these delete rules
https://developer.apple.com/library/ios/documentation/Cocoa/Conceptual/CoreData/HowManagedObjectsarerelated.html
Relationship Delete Rules
A relationship's delete rule specifies what should happen if an
attempt is made to delete the source object. Note the phrasing if an
attempt is made. If a relationship's delete rule is set to Deny, it is
possible that the source object will not be deleted. Consider again a
department's employees relationship, and the effect of the different
delete rules.
Deny If there is at least one object at the relationship destination
(employees), do not delete the source object (department).
For example, if you want to remove a department, you must ensure that
all the employees in that department are first transferred elsewhere
(or fired!); otherwise, the department cannot be deleted.
Nullify Remove the relationship between the objects but do not delete
either object.
This only makes sense if the department relationship for an employee
is optional, or if you ensure that you set a new department for each
of the employees before the next save operation.
Cascade Delete the objects at the destination of the relationship when
you delete the source.
For example, if you delete a department, fire all the employees in
that department at the same time.
No Action Do nothing to the object at the destination of the
relationship.
For example, if you delete a department, leave all the employees as
they are, even if they still believe they belong to that department.
It should be clear that the first three of these rules are useful in
different circumstances. For any given relationship, it is up to you
to choose which is most appropriate, depending on the business logic.
It is less obvious why the No Action rule might be of use, because if
you use it, it is possible to leave the object graph in an
inconsistent state (employees having a relationship to a deleted
department).
If you use the No Action rule, it is up to you to ensure that the
consistency of the object graph is maintained. You are responsible for
setting any inverse relationship to a meaningful value. This may be of
benefit in a situation where you have a to-many relationship and there
may be a large number of objects at the destination.
I am new to core data just started learning the new ideas in core data.
I have core data database which has three entity Student,Department and an entity for Mapping Student and department.Let name it as StudentDepartment
Student will have all student details with a primary key studentID
Department will have department details with a primary key departmentID
StudentDepartment will have studentID and DepartmentID as foreign key.
Multiple student can be enrolled in a department and a same student can be enrolled to multiple department.
How to create this schema in core data.
If am deleting a studentID in student table subsequent row should be deleted in StudentDepartment table. Similarly if am deleting departmentID in department table subsequent rows should be deleted in StudentDepartment.How to make this relationship by using core data.
Please provide me a xcmodel.
CoreData isn't a database, it's an object store that happens to (sometimes) be implemented on top of a relational database.
The practical result of that is that you really don't need to explicitly create a separate table for relationship mapping. Instead you create your two entities and then create a relationship between the two. From your description, it sounds like you want a many-to-many relationship between the two. At an implementation level, core data will magically create the needed relationship table.
Additionally, you can establish a delete-rule for each side of the relationship that mandates what to do when an item is deleted. Pin this case, you'll want to set the delete rule for both to nullify, which will break the relationship when either end is deleted.
I am a little fuzzy about Core Data Relationships deletion rules. So if someone could help me answer a few questions about them.
I have Entities A and B. A has a to-Many relationship with B, and B has a to-One relationship with A.
A<--->>B
Now, if I set the delete rule at A to Cascade, I understand it will delete all the Bs related to it. But if I set it to Nullify, will it set the Bs to NIL or just the Foreign Key to Nil?
And I looked everywhere about the relationship from B to A, should I set it to Nullify? Will that just Nullate the "B Object" at A? Or will it Nullify all the Bs associated with A? What about Cascade? Will it delete all the Bs associated with A, or just the particular B?
Or do I just use "No Action" on the relation from B to A so that when I delete B, no change will happen to A, but the reference to B won't exist?
I am PRETTY confused with these, so excuse my questions.
Thanks.
If you set the delete rule to "nullify" and delete the A object, then the references to that object in the Bs will be removed. The inverse works the same way. If you have cascade and delete B then it will remove the A that B pointed to. It will then follow the delete rule from A to the remaining Bs (either cascade or nullify).
The rules you set really depend on your data model. If A were a customer and B were their orders then you could set the A->B rule to deny (prevent A from being deleted if it the customer has orders) or cascade (delete the orders when the customer is deleted). The B->A rule would probably be "nullify". If an order is deleted simply remove the reference to the order from the customer.
The relationship delete rules are described in the Apple Core Data Programming Guide
More deep explanation and visualization with delete rule.
Let be assume we have database with table person and work. Single person can have many tasks to do.
Sample data and ER relationship
Delete Rule Explation
No Action : If I add this delete rule on relationship and then delete one of the person then it will not do anything with the task but person got deleted. The task still points to the person that we deleted.
Use Case: I don't think it is used anywhere.
Nullify : If I apply this delete rule and delete the person then associate tasks will points to the null person. For example, I deleted the thor and thor tasks will point to the null person. Check below output.
Use Case : Let's assume we have DB with Person and address. Now person sells his house to broker. In this case you can null the person of that address and reassign the owner to that house when new Person purchased that house.
Cascade : In this rule, if I deletes the person then it will deletes all the tasks associated with that person. For example, I deletes the Spiderman, check below output.
Use Case: Let be assume we have a user and his friends list. If user account deleted then we also want to delete the friend list.
Deny : Now we have person i.e. IronMan with 2 tasks. In this rule, if I try to delete the Iron Man then it does not allow me to do. It gives error "The operation couldn’t be completed. (Cocoa error 1600.)" on saving the context. Now to delete the Iron Man person, we need to delete all his associated tasks and then we could able to delete the Person.
Use Case: Lets assume, there is a user with bank account. We can not delete the user from the bank until his account is not closed.
if you set "nullify" and delete A's object , A's object and the back relationship only will get deleted not B's object.
eg : Customer entity has nullify relationship to orders . and if you delete a customer from customer entity, it will just delete customer and its back relationship from order . it wont remove the orders the customer made
but if the relationship is "cascade" it will remove the customer and his orders .
if it is "deny" . if the customer has any order , it wont delete delete the customer even .
I have two entities: patient and checkpoint.
Patient has attributes such as DOB, name, ID, etc.
Checkpoint has attributes such as dateRecorded, height, weight, etc.
You probably get the idea- I want there to be a set of patients, and then each patient can have checkpoints associated with that patient.
On both entities, how should I set the settings? The settings are:
I looked at the documentation for this, and I was still confused. I think what I want is a one to many relationship (for patient), but then I'm not sure how to set the inverses for either of them, or the delete rule and the other stuff. THANK YOU!!
I just got started with Core Data this week. Great question!
Relationships:
Since one patient can have many checkpoints, the Patient to Checkpoint relationship is a One to Many relationship. The concept of an "inverse relationship" is essentially this: You've got a relationship going one way (Patient to Checkpoint) - now go ahead and look at it from the inverse, the Checkpoint's perspective. A checkpoint can apply to only a single patient. Therefore, the Checkpoint to Patient relationship is a One to One relationship.
Inverse Relationships:
To handle the inverse relationship, simply create each relationship, ignoring the inverse. Then, after you have the relationship on each object, go ahead and define the inverse as the relationship on the other entity.
In other words, a relationship points to another entity or a group of entities. An inverse relationship points to a relationship on another entity.
Delete Rules:
As far as delete rules are concerned, it's fairly simple. When trying to delete a patient which has checkpoints...
Deny: Core Data won't let you delete the Patient.
Cascade: Core Data will delete the Entity (Patient), as well as cascading through relationships and deleting those objects as well. (In other words, Core Data will delete the Checkpoint objects too.)
Nullify: Core Data will delete the patient but first remove the relationship. The Checkpoint will remain intact.
For the Patient entity might want either deny or cascade, depending on how you want to manage your data. Based on your usage case, you probably don't want nullify, since Checkpoints are dependent upon Patient entities.
You want nullify for the Checkpoint, since the Cascade would prevent you from deleting a checkpoint without deleting the entire patient, and Deny would effectively force the same.
Based on the scenario mentinoed, it looks like a one to many relationship between patient and checkpoint tables.
Now add a relationship from “Patient” to “Checkpoint”, and also set the inverse between the tables.
Also, set the delete rule for both relationships to “cascade”. This means that if you delete one object with Patient, the corressponding Coredata will delete the associated object as well.