Relations entre modèles dans NSManagedObjectModel à partir de modèles fusionnés?
-
02-07-2019 - |
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?
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.