relações inter-modelo em NSManagedObjectModel de modelos incorporadas?
-
02-07-2019 - |
Pergunta
É possível relacionamentos modelo entre entidades que são definidas no NSManagedObjectModels separadas se as entidades são sempre utilizados dentro de uma NSManagedObjectModel que é criado mediante a fusão das modelos relevantes?
Por exemplo, digamos modelo 1 define um Foo
entidade com relação (one-to-one) toBar
e que o modelo 2 define uma Bar
entidade com uma toFoo
relacionamento (one-to-one). Vou construir uma pilha CoreData usando -[NSManagedObjectModel mergedModelFromModels]
, modelo 1 e modelo 2. fusão Existe alguma maneira para definir essas relações tanto no modelador de dados ou através de programação para que eles se comportam como se fossem relacionamentos em-modelo?
Solução
Nem modelo 1 nem modelo 2 será carregável em tempo de execução, a menos que eles são bem-formado - isto é, a menos que as relações toBar
e toFoo
têm destinos. Além disso, se o modelo 1 e modelo 2 têm modelos com nomes idênticos, você não será capaz de criar um modelo mesclado a partir deles; eles não serão fundiram, eles vão colidir, o que é um erro.
No entanto, você pode usar a API NSManagedObjectModel
manualmente para carregar cada modelo e criar um novo modelo à mão que contém entidades de ambos. As classes NSEntityDescription
e NSPropertyDescription
(e suas subclasses) fazer implementar o protocolo NSCopying
assim na maioria dos casos, você deve apenas ser capaz de copiar as propriedades ao longo de cada modelo de componentes para o modelo geral.
Além disso, as classes NS*Description
todo o apoio um dicionário userInfo
que você pode editar em dados do Xcode modelagem ferramenta, que você pode usar para fazer coisas como tag o destino de um relacionamento como um stand-in. Por exemplo, no modelo 1 você poderia ter uma entidade Bar
com um userInfo
chave MyRealEntity
e verifique se que ao criar seu modelo mesclado, como um sinal para usar a entidade real em vez.
Você também vai querer colocar stand-in relações inversas para o seu stand-in entidades; estes serão substituídos por inversas reais após a fusão. Você não tem de se replicar totalmente o seu stand-in entidades em todos os modelos, embora; você só precisa as relações inversas usados ??em seu modelo real em um estande na entidade.
Assim, se o seu Foo
real tem um atributo name
, e sua verdadeira Bar tem um atributo kind
, o seu stand-in Foo
e Bar
não vai precisar desses, apenas dublê toBar
e toFoo
relacionamentos.
Aqui está um código demonstrando o que eu estou falando:
- (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;
}
Isso funciona porque a cópia de objetos NS*Description
em Core Data é por nome, em vez de por valor em relação à entidade destino de um relacionamento e inversa (e subentidades de uma entidade também). Assim, enquanto um modelo é mutável - isto é, antes que seja definido como o modelo para uma NSPersistentStoreCoordinator
-. Você pode usar truques como este para quebrar o seu modelo em vários modelos