Maintaining integrity of Core Data Entities with many incoming one-to-many relationships
I have a Core Data store which contains a number of MediaItem entities that describe, well, media items. I also have NewsItems, which have one-to-many relationships to a number of MediaItems. So far so good.
However, I also have PlayerItems and GalleryItems which also have one-to-many relationships to MediaItems. So MediaItems are shared across entities.
Given that many entities may have one-to-many relationships, how can I set up reciprocal relationships from a MediaItem to all (1 or more) of the entities which have relationships to it and, furthermore, how can I implement rules to delete MediaItems when the number of those reciprocal relationships drops to 0?
For the record (and in case it comes in useful to somebody else), I solved this by creating an abstract MediaLinkedEntity
class with a one-to-many relationship to MediaItems
(named MediaItems
at the MediaLinkedEn开发者_开发技巧tity
end and LinkedEntities
at the MediaItem
end). I then subclassed this entity for NewsItems
and GalleryItems
and implemented the following -prepareForDeletion
method in MediaLinkedEntity
:
- (void)prepareForDeletion {
NSSet *mediaItems = self.MediaItems;
NSSet *linkedEntities;
// step through all media items we link to
for( MediaItem *mediaItem in mediaItems ){
linkedEntities = mediaItem.LinkedEntities;
if( [ linkedEntities count ] == 1 && [ linkedEntities containsObject: self ] ){
// if this MediaLinkedEntity is the only entry in the mediaItem's linked entities list, delete it.
[ mediaItem.managedObjectContext deleteObject: mediaItem ];
}
}
[ super prepareForDeletion ];
}
Essentially, following Marcus's answer below.
The best answer for this is to have an abstract parent entity that handles the relationship in a generic way. This will allow you to reduce the number of relationships in your model.
As for the delete rule, you should create a subclass for "one" side of the relationships and implement their -prepareForDeletion
method to check for orphaned items on the many side and then delete them when it occurs.
However, I also have PlayerItems and GalleryItems which also have one-to-many relationships to MediaItems. So MediaItems are shared across entities.
The easiest but not so beautiful way would be to create inverse relationships for each of the MediaItem relations.
Another possibility would be to create an abstract parent entity with a relation to MediaItem and inherit GalleryItem, NewsItems, PlayerItem from this general entity.
Given that many entities may have one-to-many relationships, how can I set up reciprocal relationships from a MediaItem to all (1 or more) of the entities which have relationships to it and, furthermore, how can I implement rules to delete MediaItems when the number of those reciprocal relationships drops to 0?
There are several ways to create this behaviour. You could use KVO to observe all the inverse relations of MediaItem
精彩评论