【问题标题】:ios/xcode/coredata: Data model for many to many relationshipsios/xcode/coredata:多对多关系的数据模型
【发布时间】:2015-05-01 03:18:02
【问题描述】:

来自 mysql 后台的 IOS newb 正在开发与 Web 服务器后端相关的应用程序。如果我有两个实体或对象享受多对多关系,例如项目和标签,在 MYSQL 中我将有三个表,即项目表、标签表和第三个标签-项目关系表。

表 1 标签 ID|标签

表 2 项目 ID|项目

表 3 标记项 ID|t​​agid|itemid

如果我想在核心数据中执行此操作,是否也适合同时拥有三个实体?

实体 1:标签 id|标签名

实体 2:物品 id|项目名称

实体 3:标记项目 id|tagid|itemid

看起来很简单,但只是想确保我正确理解核心数据。

【问题讨论】:

标签: ios core-data many-to-many


【解决方案1】:

如果你的中间表没有其他属性,那么你不需要自己建模。只需创建从Entity 1Entity 2 的一对多关系,以及从Entity 2Entity 1 的一对多关系,并使每个关系成为另一个关系的逆。 CoreData 将为您构建和管理中间表(它的存在很大程度上对您隐藏)。模型编辑器应如下所示:

当您生成子类时,CoreData 将为关系创建 NSSet 属性:

Tag.h
#import <Foundation/Foundation.h>
#import <CoreData/CoreData.h>

@class Item;

@interface Tag : NSManagedObject
@property (nonatomic, retain) NSString * tagName;
@property (nonatomic, retain) NSSet *items;
@end

@interface Tag (CoreDataGeneratedAccessors)
- (void)addItemsObject:(Item *)value;
- (void)removeItemsObject:(Item *)value;
- (void)addItems:(NSSet *)values;
- (void)removeItems:(NSSet *)values;
@end

Item.h
#import <Foundation/Foundation.h>
#import <CoreData/CoreData.h>

@class Tag;

@interface Item : NSManagedObject
@property (nonatomic, retain) NSString * itemName;
@property (nonatomic, retain) NSSet *tags;
@end

@interface Item (CoreDataGeneratedAccessors)
- (void)addTagsObject:(Tag *)value;
- (void)removeTagsObject:(Tag *)value;
- (void)addTags:(NSSet *)values;
- (void)removeTags:(NSSet *)values;
@end

然后您可以使用核心数据生成的访问器来添加和删除关系 - 请注意,您直接设置对象之间的关系,您不必使用 ID; CoreData 正在“暗中”为您处理 ID。所以你可以这样做:

Tag *actionTag = [NSEntityDescription insertNewObjectForEntityForName:@"Tag" inManagedObjectContext:self.context];
actionTag.name = @"Action";
Tag *dramaTag = [NSEntityDescription insertNewObjectForEntityForName:@"Tag" inManagedObjectContext:self.context];
dramaTag.name = @"Drama";

Item *movie = [NSEntityDescription insertNewObjectForEntityForName:@"Item" inManagedObjectContext:self.context];
movie.name = @"Pride and Prejudice";
[movie addTagsObject:dramaTag];    

如果您的中间表确实有其他属性,那么您应该实现Entity 3,并添加您需要的任何属性(但不要实现“id”键 - 将其留给 CoreData)。从Entity 1Entity 3 的关系应该是对多的,但它的逆应该是对一的;同样从Entity 2Entity 3 应该是多对多,它的逆对一:

Entity 2 <---->> Entity 3 <<----> Entity 1

【讨论】:

  • 但是只有一些项目有一些标签。必须有一种方法让核心数据知道哪些标签有哪些实体。例如,如果项目是电影,标签是动作和戏剧,你必须告诉底层数据库这部电影是动作,那部电影是戏剧。有没有办法在没有第三张桌子的情况下做到这一点?
  • 我会扩展我的答案。
  • 这是有道理的。当我问这个问题时,你的回答似乎是正确的。但是,为了澄清这些标签是用户生成的而不是硬编码的,因此可能有无限数量的组合。在这种情况下,我是否可以使用第三张表,或者我会错过核心数据的力量?
  • 双实体解决方案应该能够处理无限数量的组合 - 您可以为一个项目添加任意数量的标签(或者为一个标签添加任意数量的项目)。但是使用中间实体是可以的,它不会显着限制 CoreData。
猜你喜欢
  • 2014-05-06
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
相关资源
最近更新 更多