2009-07-17 8 views
13

Quiero buscar los objetos B que tienen una relación muchos con el objeto A (es decir, A - >> B). Ya tengo A en la memoria. Sé que podría obtener un NSSet de los objetos B de A, pero ¿sería mejor hacer una solicitud de búsqueda de los objetos B (especialmente si quiero ordenar las secciones por fecha en una UITableView)?Obtención de datos básicos Objetos que están en relación con otro objeto

¿Cómo puedo hacer una solicitud que solo obtiene los objetos B que pertenecen a un único objeto A?

Respuesta

5

Debe especificar una relación inversa en Clase B para hacer lo que está preguntando.

Sin embargo, no estoy seguro de por qué se opone (sin juego de palabras) a agarrar el conjunto de objetos B que ya están en el objeto A. Aunque los objetos en sí están cargados de pereza, ya que tiene A en la memoria, tengo la corazonada (aunque un experto debería verificar) que sería más eficiente simplemente tomar el conjunto de A que especificar un nuevo NSPredicate, y crear un Fetch completamente nuevo.

Por supuesto, por "más eficiente" estamos hablando de milisegundos, incluso en un dispositivo tan lento como el iPhone. Tomaría el conjunto del objeto A porque la sintaxis es más clara. El hecho de que también puede ser más rápido es una ventaja.

+1

Me gustaría hacer esta pregunta porque quiero que los objetos B sean ordenados por fecha. Y pensé que podría ser más rápido y menos intensivo en la CPU que la base de datos central preseleccionara un conjunto grande (potencialmente más de 200) de objetos en lugar de usar código. –

+0

Devin: si desea ordenar los objetos B, debe agregarlos a la pregunta original. ¡Me gustaría saber la respuesta también! –

+0

También estoy interesado en: http://stackoverflow.com/questions/4003659/is-it-possible-to-have-core-data-sort-the-many-part-of-a-to- many -relación-d. Sé que puedes forzar un error por lotes. Me pregunto si puedes ordenarlo cuando lo hagas. – JoBu1324

6

Si ya tiene una instancia de A, solo tiene que acceder a las instancias B relacionadas a través del acceso de A.

Si necesita a buscar directamente a todos está relacionado con una determinada A (no lo hace en este caso) el B, que le construya una solicitud de la entidad B FETCH, con un predicado sobre la base de la relación (inversa) de Bs a A. (La sintaxis específica dependerá del nombre de la relación inversa, y si ese inverso es un uno o muchos).

2

Estoy en una situación similar.

Quiero usar NSFetchedResultsController para administrar B en la relación uno a muchos (A - >> B). Ahora, una forma de hacer esto es crear un predicado como la siguiente y aplicarlo a la entidad B:

NSPredicate *Predicate = [NSPredicate predicateWithFormat: 
            @"ANY hasParent.label == 'A'"]; 

Pero esta es una manera terriblemente lento de hacer las cosas y debe ser evitado a toda costa. Intenté esto en 25,000 objetos para recuperar unos 300 y el simulador tardó unos 15 segundos. No terminaría la búsqueda en el iPhone y se estrelló repetidamente.

La otra manera sería hacer lo que ya se ha mencionado, crear un NSArray del conjunto que A posee y ordenarlo. Si envía allObjects a un conjunto, obtiene una matriz de nuevo. A es un NSManagedObject obtenido antes.

NSSortDescriptor *sortDescriptor = [[NSSortDescriptor alloc] 
            initWithKey:@"Name" 
            ascending:YES]; 

NSArray *lotsOfB = [[[A hasRelationsTo] 
        allObjects] 
        sortedArrayUsingDescriptors: sortDescriptors]; 

Esto es muy rápido. Sin retraso en el simulador o en el dispositivo. Pero no se puede utilizar un NSFetchedResultsController momentos tristes :-(

Espero que ayude.

0

También estoy en una situación similar.

No tenía tanto objetos como pingbat hace, pero tomó 15 segundos para buscar con "CUALQUIERA hasParent.label == 'A'"

Necesito usar NSFetchedREsultsController, por lo tanto, tengo que volver a diseñar el modelo. Lo que hice fue almacenar la relación to-many como una propiedad de cadena y construir el predicado "hasParent contains% @".

La lección que aprendí es que tener un predicado que en sentido transverso una relación a muchos tiene un impacto en el rendimiento BIG ..

5

Es necesario utilizar el predicado con IDobjeto de su A, de esta manera:

NSFetchRequest *fetchRequest = [[NSFetchRequest alloc] init]; 

NSEntityDescription *BEntity = [NSEntityDescription entityForName:@"B" inManagedObjectContext:moc]; 
[fetchRequest setEntity:BEntity]; 

NSPredicate *predicate = [NSPredicate 
predicateWithFormat:@"(relationship_to_a = %@)", [yourAInstance objectID]]; 

[fetchRequest setPredicate:predicate]; 

donde relationship_to_a es el nombre de la relación con A en su objeto gestionado B.

Espero que esto ayude.

Por cierto: a todas esas otras respuestas que sugieren usar las fallas del conjunto de relaciones: lo he intentado yo mismo, y fue mucho más lento que buscarlas, porque Core Data aparentemente dispara las fallas una tras otra (no en lote), lo que lo hace muy lento para conjuntos más grandes.

En realidad, si usted consigue su Una instancia por ir a buscar, a continuación, se puede tratar de establecer relationshipKeyPathsForPrefetching en su NSFetchRequest a YES, y luego todos los objetos en la relación no debe ser faltas. Pero esto no funcionó para mí, así que me quedé con la 'solución de búsqueda'.

Cuestiones relacionadas