Pregunta

¿Es posible modelar relaciones entre entidades que se definen en NSManagedObjectModels separados si las entidades siempre se usan dentro de un NSManagedObjectModel que se crea al fusionar los modelos relevantes?

Por ejemplo, digamos que el modelo 1 define una entidad Foo con una relación (uno a uno) toBar y que el modelo 2 define una entidad Barra con una relación (uno a uno) toFoo . Construiré una pila CoreData usando - [NSManagedObjectModel mergedModelFromModels] , fusionando el modelo 1 y el modelo 2. ¿Hay alguna forma de definir estas relaciones en el modelador de datos o programáticamente para que se comporten como si fueran relaciones en el modelo?

¿Fue útil?

Solución

Ni el modelo 1 ni el modelo 2 podrán cargarse en el tiempo de ejecución a menos que estén bien formados, & nbsp; es decir, a menos que las relaciones toBar y toFoo tengan destinos . Además, si el modelo 1 y el modelo 2 tienen modelos con nombres idénticos, no podrá crear un modelo combinado a partir de ellos; no se fusionarán, chocarán, lo que es un error.

Sin embargo, puede usar la API NSManagedObjectModel manualmente para cargar cada modelo y crear un nuevo modelo a mano que contenga entidades de ambos. Las clases NSEntityDescription y NSPropertyDescription (y sus subclases) implementan el protocolo NSCopying , por lo que en la mayoría de los casos solo debería poder copiar las propiedades de cada modelo de componente para su modelo global.

Además, las clases de NS * Description son compatibles con el diccionario userInfo que puede editar en la herramienta de modelado de datos de Xcode, que puede usar para hacer cosas como etiquetar el destino de una relación como suplente. Por ejemplo, en el modelo 1 podría tener una entidad Bar con una clave userInfo MyRealEntity y verificar esto al crear su modelo fusionado, como un señal para usar la entidad real en su lugar.

También querrá establecer relaciones inversas de soporte para sus entidades de soporte; Estos serán reemplazados con inversiones reales después de la fusión. Sin embargo, no tiene que replicar totalmente sus entidades suplentes en todos los modelos; solo necesita las relaciones inversas utilizadas en su modelo real en un stand en entidad.

Por lo tanto, si su Foo real tiene un atributo nombre , y su barra real tiene un atributo tipo , su stand-in Foo y Bar no los necesitarán, solo las relaciones de toBar y toFoo .

Aquí hay un código que demuestra de lo que estoy hablando:

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

Esto funciona porque la copia de los objetos NS * Description en los Datos del Core se realiza por nombre en lugar de por valor con respecto a la entidad de destino de la relación e inversa (y también a las subentidades de la entidad). Por lo tanto, si bien un modelo es mutable, & nbsp; es decir, antes de que se establezca como el modelo para un NSPersistentStoreCoordinator , puedes usar trucos como este para dividir tu modelo en múltiples modelos.

Licenciado bajo: CC-BY-SA con atribución
No afiliado a StackOverflow
scroll top