2013-06-10 24 views
13

Tôi vừa mới bắt đầu tìm hiểu cách triển khai Mô hình dữ liệu cốt lõi trên iOS. Sau một số hướng dẫn cơ bản về cách lưu trữ và truy xuất dữ liệu với mối quan hệ 1-1 giữa các thực thể, tôi hiện đang cố gắng thực hiện mối quan hệ một đến nhiều. mô hình dữ liệu của tôi bao gồm hai thực thể với các lớp tương ứng của họ được xác định như sau:Dữ liệu chính: Chèn vào mối quan hệ một đến nhiều

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 

tôi thấy câu hỏi tương tự được sử dụng để chèn NSMutableSet, nhưng tôi không thể thực hiện tương tự cho một mảng NSMutable.

Hiện nay mã chèn của tôi trông giống như:

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

tôi lấy dữ liệu cho nhà hàng và Nhận xét của nó thông qua JSON và lưu trữ chúng trong các lớp học tạm thời trước khi lưu chúng vào cơ sở dữ liệu CORE. Làm cách nào để chèn dữ liệu như vậy có mối quan hệ Một đến Nhiều?

EDIT: Hiện nay tôi nhận được dữ liệu trong các hình thức của một lớp trong đó xác định các bất động sản user_review như

NSMutableArray *user_reviews; 

Tôi cố gắng để thực hiện lớp này cùng để chèn vào mô hình dữ liệu cốt lõi. Nhưng mô hình dữ liệu lõi sử dụng NSSet thay vì NSMutableArray. Một cách tiếp cận brute là sao chép tất cả các lớp có cùng thuộc tính ngoại trừ thay vì sử dụng NSMutableArray, tôi thay đổi nó thành NSSet. Nhưng điều này tạo ra một lượng lớn mã dự phòng. Không nên có một cách hiệu quả hơn để làm điều này?

Trả lời

20

nếu xét của bạn sẽ là một mối quan hệ trong coreDataModel của bạn, hãy sử dụng thay vì NSMutableArray các NSSet và kết nối nó với các nhà hàng Entity.

Trong Đánh giá: enter image description here

Trong nhà hàng: enter image description here

Nếu bạn để xcode tạo lớp học của bạn, nó sẽ giống như thế này:

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 

Cuộc gọi của bạn sẽ là:

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 

chỉnh sửa

Nếu nó phải là số NSMutableArray, nó không thể là một sự đánh giá lại.
Đó luôn là NSSets (nếu x đến n) hoặc các lớp đích. Sử dụng NSMutableArray lấy các ưu điểm của bộ và xử lý tự động.

Nhưng nếu bạn thực sự muốn để lưu trữ trong NSMutableArray, tôi recommand để mở rộng lớp Review của bạn ít nhất bằng một reviewID thuộc tính (duy nhất) và lưu trữ các NSMutableArray như 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 
} 
+0

Phải, chỉ cần sao chép/dán mã của bạn ở phần này ^^ có vấn đề gì nếu chúng không phải là 'NSObjects' nhưng 'NSManagedObjects'? Nếu có lý do chống lại giải pháp này, hãy cho tôi biết :) – geo

+0

* "... theo như tôi nhớ" * - đó * là * chính xác nếu Restaurant.user_reviews và Review.restaurant được thiết lập là ** mối quan hệ nghịch đảo * *, như ảnh chụp màn hình cho biết. –

+0

Đó là vấn đề. Lần đầu tiên tôi tải toàn bộ dữ liệu từ một API trực tuyến với sự trợ giúp của RestKit 0.20. Restkit tải tất cả các mối quan hệ trong một mảng thay vì một NSSet. Tôi đã xác định một lớp cho "Restaurant.h" cho Restkit để tải/dữ liệu bản đồ vào. Bây giờ tôi đang cố gắng lưu trữ dữ liệu bằng cách tải nó vào Mô hình Dữ liệu Chính, để nó có sẵn để truy cập ngoại tuyến. Nhưng để làm điều đó tôi cần phải tạo ra các lớp học cho mỗi thực thể. Tôi đang cố gắng sử dụng lại các lớp tôi đã tạo cho API RestKit, vì mọi thứ đều giống nhau, ngoại trừ NSMutableArray và NSSet. – Kyuubi

1
Review *review = (Review *)[NSEntityDescription insertNewObjectForEntityForName:@"Review" inManagedObjectContext:[self managedObjectContext]]; 
review.review_text = @"test text"; 
//set other properties if needed 

rest.user_reviews = [NSSet setWithObjects:review, nil];//just make NSSet for you reviews 
+0

Điều này sẽ không hoạt động. Mối quan hệ với nhiều dữ liệu cốt lõi được mô hình hóa là NSSet, không phải là mảng NS (Mutable). –

+0

ok thay đổi bệnh cho NSSet =) –

Các vấn đề liên quan