2009-07-22 48 views
42

Tengo un modelo de datos básicos en el que una entidad de tarea incluye una relación opcional a muchos excluidaOcurrencias. Una de las propiedades de excluidOccurrences es start, que es un objeto NSDate. La entidad ExcludedOccurrence tiene una relación inversa obligatoria one-to con la entidad Task.Datos básicos, NSPredicate y to-many clave

Para recuperar tareas para un día específico, necesito asegurarme de que el día especificado no aparezca como la propiedad de inicio de ninguna entidad ExcludedOccurrence. Uno de los sub-predicados que estoy tratando de usar es, por tanto,

NSPredicate *occurrenceIsNotExcludedPredicate = [NSPredicate predicateWithFormat: @"(ALL excludedOccurrences.start != %@))", today]; 

donde hoy se encuentra un objeto NSDate para hoy incluyendo sólo los componentes día, mes y año. Todas las propiedades de inicio de ocurrencias excluidas también incluyen solo los componentes de día, mes y año.

Si bien esto debería bien, al menos la lectura de la documentación de la base de datos y NSPredicate, me sale el siguiente mensaje de error:

Terminación de aplicación debido a excepción no detectada 'NSInvalidArgumentException', razón: 'predicado no compatible

Si utilizo el predicado equivalente

NSPredicate *occurrenceIsNotExcludedPredicate = [NSPredicate predicateWithFormat: @"!(ANY excludedOccurrences.start == %@))", today]; 

se lanza ninguna excepción, sin embargo, el código no funciona como se esperaba: la aparición de hoy en día, que no debe ser excluido, en su lugar se excluye.

No estoy seguro también cómo probar los casos excludedOccurrences == nil: el siguiente predicado

NSPredicate *nilPredicate = [NSPredicate predicateWithFormat: @"(excludedOccurrences == nil)"]; 

causas en tiempo de ejecución excepción

-a-muchos clave no permitida aquí

Sin embargo, dado que la relación excludecurrencias es opcional, también necesito probar si es nula.

¿Cómo manejo esto? Gracias de antemano.

Respuesta

28

con la ayuda de todos ustedes, que finalmente lograron determinar el predicado correcto para mi escenario. Parece que un objeto NSDate se maneja como un doble, sin embargo, el doble nunca es algo así como 3.7, siempre es como 3.0 Por lo tanto, el siguiente predicado funciona correctamente en mis pruebas:.

NSPredicate *occurrenceIsNotExcludedPredicate = [NSPredicate predicateWithFormat: @"([email protected] == 0 || ([email protected] > 0 && NONE excludedOccurrences.start == %@))",thisDate]; 

donde thisDate es un objeto NSDate que contiene sólo los componentes día, mes y año (como en el caso de la propiedad inicio de la entidad ExcludedOccurrence

pruebas para una relación vacía se realiza básicamente mediante el operador agregado @count, según lo sugerido por algunas personas en Apple.

una vez más, gracias mucho por su ayuda. todavía observo que la documentación es deficiente en varios partes (especialmente donde dice que TODO funciona bien mientras que, en cambio, no funciona en absoluto).

108

Para probar una relación vacía, debe comparar el recuento de la clave to-many con cero.

[NSPredicate predicateWithFormat:@"[email protected] == 0"]; 

En cuanto a sus subpredicates, tenga en cuenta que sólo puede tener uno de cualquiera de los ALL o ANY modificadores en su predicado final, aunque se puede usar ese modificador varias veces durante el predicado.

No OK: ANY foo.bar = 1 AND ALL foo.baz = 2
OK:ANY foo.bar = 1 AND !(ANY foo.baz != 2)

+0

su solución de relación vacía se cuelga para mí. –

+0

Disculpa, el formato del predicado se ha corregido. Nunca me preocupé por probar mi suposición cuando se publicó, aparentemente tampoco nadie más lo hizo. –

+1

Es increíble cuánto tiempo he estado buscando probar uno-a-muchos para una relación vacía. ¡Así que me alegro de que lo hayas publicado aquí! –

8

Por lo tanto, para la prueba de una relación que no está vacía, esto realmente funciona:

[NSPredicate predicateWithFormat:@"[email protected] != 0"] 

La solución dada por Ashley Clark se bloquea por darme "a-muchos clave no permitido aquí"

+0

He corregido mi respuesta, no sé lo que estaba pensando cuando escribí eso. Mea culpa. –

Cuestiones relacionadas