Domanda

È possibile modellare le relazioni tra entità definite in NSManagedObjectModels separati se le entità sono sempre utilizzate all'interno di un NSManagedObjectModel che viene creato unendo i modelli pertinenti?

Ad esempio, supponiamo che il modello 1 definisca un'entità Foo con relazione (uno a uno) toBar e che il modello 2 definisca un'entità Bar con una relazione (one-to-one) toFoo . Costruirò uno stack CoreData usando - [NSManagedObjectModel mergedModelFromModels] , unendo il modello 1 e il modello 2. Esiste un modo per definire queste relazioni nel modellatore di dati o programmaticamente in modo che si comportino come se fossero relazioni nel modello?

È stato utile?

Soluzione

Né il modello 1 né il modello 2 saranno caricabili in fase di esecuzione a meno che non siano ben formati & # 8212; & nbsp; ovvero, a meno che toBar e toFoo le relazioni hanno destinazioni. Inoltre, se il modello 1 e il modello 2 hanno modelli con nomi identici, non sarà possibile creare un modello unito da essi; non si uniranno, si scontreranno, il che è un errore.

Tuttavia, è possibile utilizzare manualmente l'API NSManagedObjectModel per caricare ciascun modello e creare manualmente un nuovo modello che contiene entità da entrambi. Le classi NSEntityDescription e NSPropertyDescription (e le sue sottoclassi) implementano il protocollo NSCopying , quindi nella maggior parte dei casi dovresti solo essere in grado di copiare le proprietà da ogni modello di componente per il modello generale.

Inoltre, le classi NS * Description supportano tutte un dizionario userInfo che puoi modificare nello strumento di modellazione dei dati di Xcode, che puoi usare per fare cose come etichettare la destinazione di una relazione come stand-in. Ad esempio, nel modello 1 potresti avere un'entità Bar con un userInfo chiave MyRealEntity e verificarlo quando crei il tuo modello unito, come segnale invece di utilizzare l'entità reale.

Ti consigliamo inoltre di mettere relazioni inverse stand-in con le entità stand-in; questi saranno sostituiti con inversioni reali dopo l'unione. Tuttavia, non è necessario replicare totalmente le entità stand-in in tutti i modelli; hai solo bisogno delle relazioni inverse utilizzate nel tuo modello reale in uno stand in entity.

Quindi, se il tuo vero Foo ha un attributo name e la tua barra reale ha un attributo kind , il tuo stand-in Foo e Bar non ne avranno bisogno, basta solo le relazioni toBar e toFoo .

Ecco un po 'di codice che dimostra di cosa sto parlando:

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

Questo funziona perché la copia degli oggetti NS * Description nei dati core è un nome anziché un valore rispetto all'entità di destinazione di una relazione e al contrario (e anche alle entità secondarie di un'entità). Pertanto, mentre un modello è mutabile & # 8212; & nbsp; cioè, prima che sia impostato come modello per un NSPersistentStoreCoordinator & # 8212; puoi usare trucchi come questo per suddividere il tuo modello in più modelli.

Autorizzato sotto: CC-BY-SA insieme a attribuzione
Non affiliato a StackOverflow
scroll top