核心数据:插入一对多关系

Kyu*_*ubi 13 cocoa-touch core-data objective-c relational-database ios

我刚刚开始学习如何在iOS上实现核心数据模型.在关于如何使用实体之间的一对一关系存储和检索数据的一些基本教程之后,我现在尝试实现一对多关系.我的数据模型由两个实体组成,它们各自的类定义如下:

Restaurant:
@interface Restaurant :NSObject
@property (nonatomic, strong) NSString *name;
@property (nonatomic, strong) NSMutableArray *user_reviews;   /* One to Many Relation to Review Entity*/
@end

Review:
@interface Review : NSObject
@property (nonatomic, strong) NSString *rating;
@property (nonatomic, strong) NSString *review_text;
@property (nonatomic, strong) User *user;
@end
Run Code Online (Sandbox Code Playgroud)

我发现使用NSMutableSet插入的类似问题,但我无法为NSMutable数组实现相同的问题.

目前我的插入代码如下:

NSManagedObjectContext *context = [self managedObjectContext];
Restaurant *rest = [NSEntityDescription insertNewObjectForEntityForName:@"Restaurant" inManagedObjectContext:context];
rest.name = restaurant.name;
Run Code Online (Sandbox Code Playgroud)

我通过JSON检索Restaurant及其评论的数据,并将它们存储在临时类中,然后将它们保存到CORE数据库.如何插入具有一对多关系的数据?

编辑:目前我以类的形式接收数据,该类将user_review属性定义为

NSMutableArray *user_reviews;
Run Code Online (Sandbox Code Playgroud)

我试图实现这个相同的类插入核心数据模型.但核心数据模型使用NSSet而不是NSMutableArray.一种粗暴的方法是复制具有相同属性的所有类,除了使用NSMutableArray,我将其更改为NSSet.但这会产生大量的冗余代码.难道不应该有更有效的方法吗?

geo*_*geo 21

如果您的评论应该在你的coreDataModel的关系,请使用代替NSMutableArrayNSSet,它与餐厅实体连接.

在审查中: 在此输入图像描述

在餐厅: 在此输入图像描述

如果你让xcode生成你的类,它将如下所示:

Restaurant:
@interface Restaurant : NSManagedObject
@property (nonatomic, strong) NSString *name;
@property (nonatomic, strong) NSSet *user_reviews;   /* One to Many Relation to Review Entity*/

@interface Restaurant(CoreDataGeneratedAccessors)

- (void)addUser_reviewsObject:(Review *)value;
- (void)removeUser_reviewsObject:(Review *)value;
- (void)addUser_reviews:(NSSet *)value;
- (void)removeUser_reviews:(NSSet *)value;

@end

Review:
@interface Review : NSManagedObject
@property (nonatomic, strong) NSString *rating;
@property (nonatomic, strong) NSString *review_text;
@property (nonatomic, strong) User *user;
@property (nonatomic, strong) Restaurant *restaurant;
@end
Run Code Online (Sandbox Code Playgroud)

您的电话将是:

NSManagedObjectContext *context = [self managedObjectContext];
Restaurant *rest = [NSEntityDescription insertNewObjectForEntityForName:@"Restaurant" inManagedObjectContext:context];
rest.name = restaurant.name;

Review *rev = [NSEntityDescription insertNewObjectForEntityForName:@"Review" inManagedObjectContext:context];
rev.rating = @"1";
rev.review_text = @"nomnomnom";

[rest addUser_reviewsObject:rev];
// or rev.restaurant = restaurant; one of both is enought as far as I remember

// save your context
Run Code Online (Sandbox Code Playgroud)

编辑

如果它必须是a NSMutableArray,那就不可能是一种通货紧缩.
这些总是NSSets(如果是x到n)或目标类.使用NSMutableArray具有集合和自动处理的优点.

但是如果你真的想要存储NSMutableArray,我建议Review至少通过reviewID属性(唯一)扩展你的类并存储NSMutableArrayas Transformable.

//Review:

@interface Review : NSManagedObject
@property (nonatomic, strong) NSString *rating;
@property (nonatomic, strong) NSString *review_text;
@property (nonatomic, strong) User *user;
@property (nonatomic, strong) NSNumber *reviewID;
@end

//Restaurant.h:

@interface Restaurant : NSManagedObject
@property (nonatomic, strong) NSString *name;
@property (nonatomic, strong) NSSet *user_reviews; // Set of NSNumbers

- (void)addUser_reviewsObject:(Review *)value;
- (void)addUser_reviewsID:(NSNumber *)value;
- (void)removeUser_reviewsObject:(Review *)value;
- (void)addUser_reviews:(NSMutableArray *)value;
- (void)removeUser_reviews:(NSMutableArray *)value;

@end

//Restaurant.m:

- (void)addUser_reviewsObject:(Review *)value
{
    [self addUser_reviewsID:value.reviewID];
}

- (void)addUser_reviewsID:(NSNumber *)value
{
    if(![self.user_reviews containsObject:value];
        [self.user_reviews addObject:value];
}

- (void)removeUser_reviewsObject:(NSNumber *)value
{
    // follow upper logic and implement yourself
}

- (void)addUser_reviews:(NSMutableArray *)value
{
    // follow upper logic and implement yourself
}

- (void)removeUser_reviews:(NSMutableArray *)value
{
    // follow upper logic and implement yourself
}
Run Code Online (Sandbox Code Playgroud)