2009-07-17 38 views
13

Tôi muốn tìm nạp đối tượng B có mối quan hệ nhiều với đối tượng A (ví dụ: A - >> B). Tôi đã có một bộ nhớ. Tôi biết tôi có thể nhận được một NSSet của các đối tượng B từ A, nhưng nó sẽ là tốt hơn để thực hiện một yêu cầu lấy của các đối tượng B (đặc biệt là nếu tôi muốn sắp xếp các phần theo ngày trong một UITableView)?Đối tượng tìm nạp dữ liệu lõi có mối quan hệ với đối tượng khác

Làm cách nào để thực hiện yêu cầu đó chỉ nhận các đối tượng B thuộc một đối tượng A?

Trả lời

5

Bạn phải chỉ định mối quan hệ ngược lại trong Lớp B để thực hiện những gì bạn đang yêu cầu.

Tuy nhiên, tôi không chắc chắn lý do tại sao bạn đang phản đối (không có ý định chơi chữ) để nắm lấy tập hợp các đối tượng B đã có trong đối tượng A. Mặc dù các đối tượng được tải chậm, vì bạn đã có bộ nhớ A, tôi có linh cảm (mặc dù một chuyên gia sẽ cần phải xác minh) rằng sẽ hiệu quả hơn nếu chỉ đơn giản là lấy tập hợp từ A hơn là chỉ định một NSPredicate mới và tạo một Fetch hoàn toàn mới.

Tất nhiên, bằng "hiệu quả hơn", chúng tôi đang nói mili giây, ngay cả trên thiết bị chậm như iPhone. Tôi lấy bộ từ đối tượng A vì cú pháp sạch hơn. Thực tế là nó cũng có thể nhanh hơn là tiền thưởng.

+1

Tôi đã hỏi câu hỏi này vì tôi muốn các đối tượng B được sắp xếp theo ngày. Và tôi mặc dù nó có thể nhanh hơn và ít cpu hơn để có cơ sở dữ liệu lõi cơ sở dữ liệu presort một tập lớn (có khả năng 200+) của các đối tượng thay vì sử dụng mã. –

+0

Devin: nếu bạn muốn sắp xếp các đối tượng B, bạn nên thêm đối tượng đó vào câu hỏi gốc. Tôi cũng muốn biết câu trả lời! –

+0

Tôi cũng quan tâm đến điều này: http://stackoverflow.com/questions/4003659/is-it-possible-to-have-core-data-sort-the-many-part-of-a-to-many -quan hệ-d. Tôi biết bạn hàng loạt có thể buộc một lỗi. Tôi tự hỏi nếu bạn có thể sắp xếp nó khi bạn làm gì? – JoBu1324

6

Nếu bạn đang giữ một phiên bản A, chỉ cần truy cập các phiên bản B có liên quan thông qua trình truy cập của A.

Nếu bạn cần tìm nạp trực tiếp tất cả B liên quan đến A cụ thể (bạn không có trong trường hợp này), bạn sẽ xây dựng yêu cầu tìm nạp đối tượng B, với biến vị ngữ dựa trên mối quan hệ (nghịch đảo) của Bs đến A. (Cú pháp cụ thể sẽ phụ thuộc vào tên mối quan hệ nghịch đảo và liệu nghịch đảo đó có phải là một hay nhiều.)

2

Tôi đang ở trong tình trạng tương tự.

Tôi muốn sử dụng NSFetchedResultsController để quản lý B trong mối quan hệ một đến nhiều (A - >> B). Bây giờ, một trong những cách để làm điều này là để xây dựng một vị như hình dưới đây và áp dụng nó vào thực thể B:

NSPredicate *Predicate = [NSPredicate predicateWithFormat: 
            @"ANY hasParent.label == 'A'"]; 

Nhưng đây là một cách khủng khiếp chậm làm việc và nên tránh bằng mọi giá. Tôi đã thử trên 25.000 đối tượng này để lấy khoảng 300 và mất khoảng 15 giây. Nó sẽ không hoàn thành việc tìm nạp trên iPhone và bị rơi liên tục.

Cách khác là làm những gì đã được đề cập, tạo một NSArray từ tập hợp được giữ bởi A và sắp xếp nó. Nếu bạn gửi allObjects đến một bộ, bạn sẽ nhận được một mảng. A là một NSManagedObject được tìm nạp trước đó.

NSSortDescriptor *sortDescriptor = [[NSSortDescriptor alloc] 
            initWithKey:@"Name" 
            ascending:YES]; 

NSArray *lotsOfB = [[[A hasRelationsTo] 
        allObjects] 
        sortedArrayUsingDescriptors: sortDescriptors]; 

Điều này rất nhanh. Không có độ trễ trong trình mô phỏng hoặc trên thiết bị. Nhưng bạn không thể sử dụng một NSFetchedResultsController lần buồn :-(

Hy vọng rằng sẽ giúp.

0

Tôi cũng trong tình trạng tương tự.

tôi không có càng nhiều đối tượng như pingbat làm, nhưng phải mất 15 giây để tìm nạp bằng "ANY hasParent.label == 'A'"

Tôi cần sử dụng NSFetchedREsultsController, do đó tôi phải kiến ​​trúc lại mô hình. một thuộc tính chuỗi và xây dựng biến vị ngữ "hasParent chứa% @".

Bài học tôi học được là có một vị ngữ ngang một mối quan hệ với nhiều người có một buổi biểu diễn hit BIG ..

5

Bạn cần phải sử dụng vị với ObjectId của Một bạn, như thế này:

NSFetchRequest *fetchRequest = [[NSFetchRequest alloc] init]; 

NSEntityDescription *BEntity = [NSEntityDescription entityForName:@"B" inManagedObjectContext:moc]; 
[fetchRequest setEntity:BEntity]; 

NSPredicate *predicate = [NSPredicate 
predicateWithFormat:@"(relationship_to_a = %@)", [yourAInstance objectID]]; 

[fetchRequest setPredicate:predicate]; 

trong đó relationship_to_a là tên của mối quan hệ với A trong đối tượng được quản lý B của bạn.

Hy vọng điều này sẽ hữu ích.

Btw .: Đối với tất cả các câu trả lời khác gợi ý sử dụng lỗi từ tập hợp quan hệ: Tôi đã tự thử bản thân này và chậm hơn so với tìm nạp chúng, vì dữ liệu lõi dường như kích hoạt lỗi này theo lô), do đó làm cho nó đau đớn chậm cho các bộ lớn hơn.

Trên thực tế, nếu bạn nhận được cá thể A bằng cách tìm nạp, bạn có thể thử đặt relationshipKeyPathsForPrefetching trong NSFetchRequest thành CÓ, và sau đó tất cả đối tượng trong mối quan hệ không phải là lỗi. Nhưng điều này không hiệu quả với tôi, vì vậy tôi bị mắc kẹt với 'giải pháp tìm nạp'.

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