9

Có thể mô hình hóa các mối quan hệ giữa các thực thể được xác định trong NSManagedObjectModels riêng biệt nếu các thực thể luôn được sử dụng trong một NSManagedObjectModel được tạo bằng cách hợp nhất các mô hình liên quan không?Các mối quan hệ chéo mô hình trong NSManagedObjectModel từ các mô hình đã hợp nhất?

Ví dụ, nói mô hình 1 định nghĩa một thực thể Foo với mối quan hệ (one-to-one) toBar và rằng mô hình 2 định nghĩa một thực thể Bar với một mối quan hệ (one-to-one) toFoo. Tôi sẽ xây dựng một ngăn xếp CoreData bằng cách sử dụng -[NSManagedObjectModel mergedModelFromModels], sáp nhập mô hình 1 và mô hình 2. Có cách nào để xác định các mối quan hệ này trong trình mô hình hóa dữ liệu hoặc lập trình để chúng hoạt động như thể chúng là các mối quan hệ trong mô hình không?

Trả lời

16

Cả mô hình 1 lẫn mô hình 2 đều không thể tải được trong thời gian chạy trừ khi chúng được định dạng tốt - trừ khi các mối quan hệ toBartoFoo có điểm đến. Hơn nữa, nếu mô hình 1 và mô hình 2 có các mô hình được đặt tên giống nhau, bạn sẽ không thể tạo mô hình được hợp nhất từ ​​chúng; chúng sẽ không được kết hợp lại, chúng sẽ va chạm, đó là lỗi.

Tuy nhiên, bạn có thể sử dụng API NSManagedObjectModel theo cách thủ công để tải từng mô hình và tạo mô hình mới bằng tay chứa các thực thể từ cả hai. Các lớp NSEntityDescriptionNSPropertyDescription (và các lớp con của nó) thực hiện giao thức NSCopying vì vậy trong hầu hết các trường hợp, bạn chỉ có thể sao chép các thuộc tính từ mỗi mô hình thành phần sang mô hình tổng thể của mình.

Hơn nữa, NS*Description lớp tất cả các hỗ trợ một cuốn từ điển userInfo mà bạn có thể chỉnh sửa trong công cụ mô hình dữ liệu Xcode, mà bạn có thể sử dụng để làm những việc như thẻ điểm đến của một mối quan hệ như một stand-in. Ví dụ: trong mô hình 1, bạn có thể có một thực thể Bar với phím userInfoMyRealEntity và kiểm tra điều đó khi tạo mô hình đã hợp nhất của bạn, làm tín hiệu để sử dụng thực thể thực thay thế.

Bạn cũng sẽ muốn đặt các mối quan hệ nghịch đảo đứng vào thực thể độc lập của mình; chúng sẽ được thay thế bằng các nghịch đảo thực sau khi hợp nhất. Bạn không cần phải sao chép hoàn toàn các thực thể đứng trong tất cả các mô hình của bạn; bạn chỉ cần các mối quan hệ nghịch đảo được sử dụng trong mô hình thực của bạn trong một gian hàng trong thực thể.

Vì vậy, nếu bạn thực Foo có một thuộc tính name, và Bar thực sự của bạn có một thuộc tính kind, độc trong FooBar của bạn sẽ không cần những, chỉ cần đứng trong toBartoFoo mối quan hệ.

Dưới đây là một số mã chứng minh những gì tôi đang nói về:

- (NSManagedObjectModel *)mergeModelsReplacingDuplicates:(NSArray *)models { 
    NSManagedObjectModel *mergedModel = [[[NSManagedObjectModel alloc] init] autorelease]; 

    // General strategy: For each model, copy its non-placeholder entities 
    // and add them to the merged model. Placeholder entities are identified 
    // by a MyRealEntity key in their userInfo (which names their real entity, 
    // though their mere existence is sufficient for the merging). 

    NSMutableArray *mergedModelEntities = [NSMutableArray arrayWithCapacity:0]; 

    for (NSManagedObjectModel *model in models) { 
     for (NSEntityDescription *entity in [model entities]) { 
      if ([[entity userInfo] objectForKey:@"MyRealEntity"] == nil) { 
       NSEntityDescription *newEntity = [entity copy]; 
       [mergedModelEntities addObject:newEntity]; 
       [newEntity release]; 
      } else { 
       // Ignore placeholder. 
      } 
     } 
    } 

    [mergedModel setEntities:mergedModelEntities]; 

    return mergedModel; 
} 

này hoạt động vì sao chép NS*Description đối tượng trong Core Data là bởi tên tuổi chứ không phải bằng giá trị liên quan đến thực thể điểm đến của một mối quan hệ và nghịch đảo với (và các subentities của một thực thể là tốt). Vì vậy, trong khi một mô hình có thể thay đổi - tức là, trước khi nó được đặt làm mô hình cho một NSPersistentStoreCoordinator - bạn có thể sử dụng các thủ thuật như thế này để phá vỡ mô hình của bạn thành nhiều mô hình.

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