通过许多传入的一对多关系维护核心数据实体的完整性
我有一个核心数据存储,其中包含许多描述媒体项的 MediaItem 实体。我还有 NewsItems,它与许多 MediaItems 具有一对多的关系。到目前为止,一切都很好。
但是,我还有 PlayerItems 和 GalleryItems,它们也与 MediaItems 具有一对多关系。因此 MediaItems 在实体之间共享。
鉴于许多实体可能具有一对多关系,如何建立从 MediaItem 到与其有关系的所有(1 个或多个)实体的相互关系,此外,如何实现删除 MediaItem 的规则当这些相互关系的数量下降到0时?
为了记录(以防它对其他人有用),我通过创建一个与 MediaItems
具有一对多关系的抽象 MediaLinkedEntity
类来解决这个问题(在 MediaLinkedEntity
端命名为 MediaItems
,在 MediaItem
端命名为 LinkedEntities
)。然后,我为 NewsItems
和 GalleryItems
对该实体进行了子类化,并在 MediaLinkedEntity
中实现了以下 -prepareForDeletion
方法:
- (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 ];
}
本质上,如下马库斯的回答如下。
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 MediaLinkedEntity
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.
如果你对这篇内容有疑问,欢迎到本站社区发帖提问 参与讨论,获取更多帮助,或者扫码二维码加入 Web 技术交流群。
绑定邮箱获取回复消息
由于您还没有绑定你的真实邮箱,如果其他用户或者作者回复了您的评论,将不能在第一时间通知您!
发布评论
评论(2)
对此的最佳答案是有一个抽象父实体以通用方式处理关系。这将使您能够减少模型中的关系数量。
至于删除规则,您应该为关系的“一侧”创建一个子类,并实现其
-prepareForDeletion
方法来检查多侧的孤立项,然后在出现时将其删除。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.最简单但不太漂亮的方法是为每个 MediaItem 关系创建逆关系。
另一种可能性是创建一个与 MediaItem 相关的抽象父实体,并从该通用实体继承 GalleryItem、NewsItems、PlayerItem。
有多种方法可以创建这种行为。
您可以使用 KVO 来观察 MediaItem 的所有逆关系
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.
There are several ways to create this behaviour.
You could use KVO to observe all the inverse relations of MediaItem