Datos básicos: Cómo verificar la presencia de una relación de muchos a muchos

StackOverflow https://stackoverflow.com/questions/1406565

  •  05-07-2019
  •  | 
  •  

Pregunta

Tengo una " Canción " Entidad y una " Etiqueta " entidad y tienen una relación de muchos a muchos entre ellos. Una canción puede tener varias etiquetas y una etiqueta se puede aplicar a varias canciones.

Quiero comprobar si una canción tiene una etiqueta en particular asociada. Si la canción tiene la etiqueta asociada, quiero mostrar una marca de verificación en la vista de tabla.

Para una lógica similar, en Apple " TaggedLocations " código de ejemplo, se realiza la siguiente comprobación para verificar la presencia de la relación.

if ([event.tags containsObject:tag]) {
    cell.accessoryType = UITableViewCellAccessoryCheckmark;
}   

Esto puede ser ineficiente si hay muchas Etiquetas en la base de datos ya que esto las recuperará todas en la memoria. Por favor, corrígeme si me equivoco aquí.

¿Hay una manera más eficiente de verificar si la canción está asociada con una etiqueta en particular en lugar de revisar en Song.Tags?

¿Fue útil?

Solución

En realidad es bastante fácil de hacer, si está completamente sin documentar. Desea crear una solicitud de recuperación con un predicado que tenga una operación de configuración. Si imaginamos que su modelo de etiqueta tiene una propiedad llamada tagValue, el predicado que le importa es " ANY tags.tagValue == 'footag' "

NSString *tagSearch = @"footag";

// However you get your NSManagedObjectContext.  If you use template code, it's from
// the UIApplicationDelegate
NSManagedObjectContext *context = [delegate managedObjectContext];

// Is there no shortcut for this?  Maybe not, seems to be per context...
NSEntityDescription *songEntity = [NSEntityDescription entityForName:@"Song" inManagedObjectContext:context];

NSFetchRequest *request = [[NSFetchRequest alloc] init];
[request setEntity:songEntity];

// The request looks for this a group with the supplied name
NSPredicate *predicate = [NSPredicate predicateWithFormat:@"ANY tags.tagValue == %@", tagSearch];
[request setPredicate:predicate];

NSError *error = nil;
NSArray *results = [context executeFetchRequest:request error:&error];

[request release];

Otros consejos

Usted tiene razón, usar ese código recuperará todo el conjunto y la comparación de objetos puede ser bastante compleja, dependiendo de cuántas propiedades y relaciones formen parte de la entidad del objeto.

De todos modos, no se puede evitar una comparación de conjuntos para la inclusión. Probablemente, lo mejor que puede hacer es evitar obtener todas las propiedades / relaciones pidiéndole a Core Data que recupere solo objetos NSManagedObjectID.

NSFetchRequest *fetchRequest = [[NSFetchRequest alloc] init]; 
[fetchRequest setEntity:[NSEntityDescription entityForName:@"Tag" inManagedObjectContext:[self managedObjectContext]]]; 
[fetchRequest setResultType:NSManagedObjectIDResultType];

Se garantiza que los objetos NSManagedObjectID son únicos, por lo tanto, puede usarlos de forma segura para verificar la inclusión de conjuntos. Esto debería ser mucho más eficiente para una perspectiva de rendimiento.

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