Question

Est-il possible de modéliser les relations entre les entités définies dans des NSManagedObjectModels distincts si les entités sont toujours utilisées dans un NSManagedObjectModel créé en fusionnant les modèles pertinents?

Par exemple, le modèle 1 définit une entité Foo avec une relation (un à un) toBar et ce modèle 2 définit une entité Bar avec une relation (un à un) toFoo . Je construirai une pile CoreData en utilisant - [NSManagedObjectModel mergedModelFromModels] , en fusionnant les modèles 1 et 2. Existe-t-il un moyen de définir ces relations dans le modélisateur de données ou par programmation de manière à ce qu'elles se comportent comme si elles étaient relations dans le modèle?

Était-ce utile?

La solution

Ni le modèle 1 ni le modèle 2 ne peuvent être chargés au moment de l'exécution, sauf s'ils sont bien formés - c'est-à-dire, sauf si les relations toBar et toFoo ont des destinations . De plus, si les modèles 1 et 2 ont des modèles portant le même nom, vous ne pourrez pas créer de modèle fusionné à partir de ceux-ci. ils ne seront pas fusionnés, ils entreront en collision, ce qui est une erreur.

Toutefois, vous pouvez utiliser manuellement l'API NSManagedObjectModel pour charger chaque modèle et créer manuellement un nouveau modèle contenant les entités des deux. Les classes NSEntityDescription et NSPropertyDescription (et ses sous-classes) implémentent le protocole NSCopying . Dans la plupart des cas, vous devriez donc pouvoir copier les propriétés à partir de. chaque modèle composant à votre modèle global.

De plus, les classes NS * Description prennent toutes en charge un dictionnaire userInfo que vous pouvez modifier dans l'outil de modélisation de données de Xcode, que vous pouvez utiliser pour marquer, par exemple, la destination. d'une relation en tant que remplaçant. Par exemple, dans le modèle 1, vous pouvez avoir une entité Bar avec une userInfo clé MyRealEntity et le vérifier lors de la création de votre modèle fusionné, en tant que signaler à la place d'utiliser l'entité réelle.

Vous voudrez également mettre des relations inverses de remplacement dans vos entités de remplacement; ceux-ci seront remplacés par de vrais inverses après la fusion. Il n'est toutefois pas nécessaire de répliquer totalement vos entités suppléantes dans tous les modèles. vous n'avez besoin que des relations inverses utilisées dans votre modèle réel dans une entité de type stand-in.

Ainsi, si votre vrai Foo a un attribut nom et que votre véritable barre a un attribut kind , votre remplaçant Foo et Bar n'auront pas besoin de ces relations, il suffit de mettre en place les relations toBar et toFoo .

Voici un code démontrant ce dont je parle:

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

Cela fonctionne car la copie des objets NS * Description dans Core Data se fait par nom plutôt que par valeur en ce qui concerne l'entité de destination et l'inverse d'une relation (ainsi que les sous-entités d'une entité). Ainsi, même si un modèle est modifiable, c’est-à-dire avant qu’il ne soit défini comme modèle pour un NSPersistentStoreCoordinator , vous pouvez utiliser de telles astuces pour diviser votre modèle en plusieurs modèles.

Licencié sous: CC-BY-SA avec attribution
Non affilié à StackOverflow
scroll top