ios/xcode/coredata:多对多关系的数据模型

ios/xcode/coredata:多对多关系的数据模型,ios,core-data,many-to-many,Ios,Core Data,Many To Many,来自mysql后台的IOS新手正在开发一个连接到web服务器后端的应用程序。如果我有两个实体或对象享受多对多关系,比如item和tag,那么在MYSQL中我将有三个表,items表,tags表和tag-item关系的第三个表 表1标签 ID|标签 表2项目 ID |项目 表3标记项目 ID | tagid | itemid 如果我想在核心数据中这样做,是否也应该有三个实体 实体1:标签 id |标记名 实体2:项目 id |项目名称 实体3:标记项目 id | tagid | itemid 看起

来自mysql后台的IOS新手正在开发一个连接到web服务器后端的应用程序。如果我有两个实体或对象享受多对多关系,比如item和tag,那么在MYSQL中我将有三个表,items表,tags表和tag-item关系的第三个表

表1标签 ID|标签

表2项目 ID |项目

表3标记项目 ID | tagid | itemid

如果我想在核心数据中这样做,是否也应该有三个实体

实体1:标签 id |标记名

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

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


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

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

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];    

生成子类时,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

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

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

实体2>实体3查看一下,但只有一些项目有一些标记。必须有一种方法让核心数据知道哪些标签包含哪些实体。例如,如果项目是电影,标记是动作和戏剧,则必须告诉底层数据库该电影是动作,该电影是戏剧。有没有办法不用第三张表就能做到这一点?我会扩展我的答案。这很有意义。我问这个问题时,你的回答似乎是对的。然而,为了澄清这些标记是用户生成的,而不是硬编码的,因此可能有无限数量的组合。在这种情况下,我可以使用第三个表吗?或者我会错过核心数据的强大功能吗?两个实体解决方案应该能够处理无限数量的组合-您可以向一个项目添加任意数量的标记(或者向一个标记添加任意数量的项目)。但使用中间实体是可以的,它不会显著限制CoreData。