9

Ist es möglich, Beziehungen zwischen Entitäten zu modellieren, die in separaten NSManagedObjectModels definiert sind, wenn die Entitäten immer in einem NSManagedObjectModel verwendet werden, das durch Zusammenführen der relevanten Modelle erstellt wird?Modellübergreifende Beziehungen in NSManagedObjectModel aus zusammengeführten Modellen?

Angenommen, Modell 1 eine Entität Foo mit Beziehung definiert (one-to-one) toBar und Modell 2 definiert eine Entität Bar mit einer Beziehung (one-to-one) toFoo. Ich werde einen CoreData-Stack mit -[NSManagedObjectModel mergedModelFromModels] erstellen und dabei Modell 1 und Modell 2 zusammenführen. Gibt es eine Möglichkeit, diese Beziehungen entweder im Data Modeler oder programmatisch so zu definieren, dass sie sich so verhalten, als wären sie In-Model-Beziehungen?

Antwort

16

Weder Modell 1 noch Modell 2 können zur Laufzeit geladen werden, es sei denn, sie sind wohlgeformt - das heißt, es sei denn, die toBar und toFoo Beziehungen haben Ziele. Wenn Modell 1 und Modell 2 Modelle mit identischem Namen aufweisen, können Sie darüber hinaus kein zusammengeführtes Modell erstellen. sie werden nicht verschmolzen, sie kollidieren, was ein Fehler ist.

Sie können jedoch die API NSManagedObjectModel manuell verwenden, um jedes Modell zu laden und manuell ein neues Modell zu erstellen, das Elemente aus beiden enthält. Die NSEntityDescription und NSPropertyDescription Klassen (und ihre Unterklassen) implementieren das NSCopying Protokoll, so dass Sie in den meisten Fällen einfach Eigenschaften aus jedem Komponentenmodell in Ihr Gesamtmodell kopieren können. Die Klassen unterstützen außerdem ein userInfo Wörterbuch, das Sie in Xcodes Datenmodellierungstool bearbeiten können, mit dem Sie beispielsweise das Ziel einer Beziehung als Stand-in kennzeichnen können. In Modell 1 könnten Sie beispielsweise eine Bar Entität mit einem userInfo Schlüssel MyRealEntity haben und beim Erstellen des zusammengeführten Modells darauf achten, dass stattdessen ein Signal zur Verwendung der realen Entität verwendet wird.

Sie möchten auch eine umgekehrte Stand-in-Beziehung zu Ihren Stand-in-Entitäten herstellen; Diese werden nach dem Zusammenführen durch echte Inversen ersetzt. Sie müssen Ihre Stand-in-Entitäten jedoch nicht in allen Modellen vollständig replizieren. Sie benötigen nur die in Ihrem realen Modell in einem Stand in Entity verwendeten inverse Beziehungen.

Wenn also Ihre echte Foo ein name Attribut hat, und Ihre Bar hat ein kind Attribut, Ihren Stand-in Foo und Bar werden diejenigen, die nicht brauchen, gerade stehen in toBar und toFoo Beziehungen.

Hier einige Code zeigen, was ich rede:

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

Das funktioniert, weil das Kopieren von NS*Description Objekte in Core Data by-Name ist und nicht durch-Wert in Bezug auf eine Zieleinheit Beziehung und inverse (und auch auf die Untereinheiten einer Entität). Während also ein Modell veränderbar ist - das heißt, bevor es als Modell für eine NSPersistentStoreCoordinator eingestellt ist - können Sie Tricks wie dieses verwenden, um Ihr Modell in mehrere Modelle aufzuteilen.

Verwandte Themen