9

如果在通過合併相關模型創建的NSManagedObjectModel中始終使用實體,是否可以對在單獨的NSManagedObjectModels中定義的實體之間的關係進行建模?來自合併模型的NSManagedObjectModel中的跨模型關係?

例如,假設模型1定義的實體Foo用關係(一到酮)toBar和模型2限定的實體Bar有關係(一到酮)toFoo。我將使用-[NSManagedObjectModel mergedModelFromModels]構建CoreData堆棧,合併模型1和模型2.是否有任何方法可以在數據建模器中或以編程方式定義這些關係,以使它們表現得好像它們是模型內關係一樣?

回答

16

模型1和模型2都不會在運行時加載,除非它們格式正確 - 也就是說,除非toBartoFoo關係具有目標。此外,如果模型1和模型2具有相同名稱的模型,您將無法從它們創建合併模型;他們不會合並,他們會碰撞,這是一個錯誤。

但是,您可以手動使用NSManagedObjectModel API來加載每個模型並手動創建包含兩個實體的新模型。 NSEntityDescriptionNSPropertyDescription類(及其子類)確實實現了NSCopying協議,所以在大多數情況下,您應該能夠將屬性從每個組件模型複製到整個模型。

此外,NS*Description類全部支持您可以在Xcode的數據建模工具中編輯的userInfo字典,您可以使用它來執行諸如將關係的目的地標記爲待辦事項等內容。例如,在模型1中,您可以使用Bar實體和userInfoMyRealEntity,並在創建合併模型時檢查該實體是否爲使用實體的信號。

您還需要爲您的替身實體提供替代關係;這些將在合併後被真正的反轉代替。不過,您不必在所有模型中完全複製您的替身實體;你只需要在實體中的真實模型中使用的相反關係。

因此,如果你真正Fooname屬性,和你真正的酒吧擁有kind屬性,你的替身FooBar將不需要這些功能,只需替身toBartoFoo關係。

下面是一些代碼展示了什麼我談論:

- (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; 
} 

這工作,因爲在覈心數據NS*Description對象的複製是通過名字而不是價值相對於一個關係的目標實體和逆(以及一個實體的子實體)。因此,雖然模型是可變的 - 也就是說,在它被設置爲NSPersistentStoreCoordinator的模型之前 - 您可以使用這樣的技巧將您的模型分解爲多個模型。