2011-06-16 14 views
6

Estoy trabajando con varios tipos de NSManagedObject con varias relaciones. ¿Cómo puedo decirle a Core Data que rellene automáticamente ID de objeto para mí? Estoy buscando algo así como una clave de índice en SQL, por lo que no se permite que dos instancias de un objeto determinado tengan la misma ID.Id. De objeto autoincrementado en datos centrales

Editar:

me gustaría que todos mis objetos "cuenta" para tener identificadores únicos en ellos. Solo estaba agregando uno a `countForFetchRequest, pero me di cuenta de que al eliminar el penúltimo objeto y luego agregar uno, los dos últimos objetos ahora tienen los mismos ID.

¿Cómo puedo asegurarme de que un valor dado tenga un valor único para todas las instancias de mi "Cuenta" NSManagedObject?

Edit2:

Es necesario disponer de un identificador separado para fines de clasificación.

Respuesta

4

La forma en que resolví esto es con los agregados de Core Data. De hecho, termino asignando la identificación yo mismo.

Básicamente, busco Datos básicos para todos los ID de entidades de mi entidad y luego los repito a través de ellos. Si encuentro un ID que es más alto que el temporal actual, hago que el ID temporal sea más alto que el agregado. Cuando termino, automáticamente tengo una identificación que es más alta que la más alta en la lista. El único defecto que veo con esto es si falta una identificación. (Creo que hay una solución simple para esto también.)

// 
// Create a new entity description 
// 

NSEntityDescription *entity = [NSEntityDescription entityForName:@"MyEntity" inManagedObjectContext:self.managedObjectContext]; 

// 
// Set the fetch request 
// 

NSFetchRequest *fetchRequest = [[[NSFetchRequest alloc] init] autorelease]; 
[fetchRequest setEntity:entity]; 

// 
// We need to figure out how many 
// existing groups there are so that 
// we can set the proper ID. 
// 
// To do so, we use an aggregated request. 
// 

[fetchRequest setResultType:NSDictionaryResultType]; 
[fetchRequest setPropertiesToFetch:[NSArray arrayWithObject:@"entityID"]]; 

NSError *error = nil; 

NSArray *existingIDs = [self.managedObjectContext executeFetchRequest:fetchRequest error:&error]; 


if (error != nil) { 

    // 
    // TODO: Handle error. 
    // 

    NSLog(@"Error: %@", [error localizedDescription]); 
} 

NSInteger newID = 0; 

for (NSDictionary *dict in existingIDs) { 
    NSInteger IDToCompare = [[dict valueForKey:@"entityID"] integerValue]; 

    if (IDToCompare >= newID) { 
     newID = IDToCompare + 1; 
    } 
} 

// 
// Create the actual entity 
// 

MyEntity *newEntity = [[MyEntity alloc] initWithEntity:entity insertIntoManagedObjectContext:self.managedObjectContext]; 

// 
// Set the ID of the new entity 
// 

[newEntity setEntityID:[NSNumber numberWithInteger:newID]]; 

// 
// ... More Code ... 
// 
+0

No necesita buscar todas las filas, solo use ÚLTIMO ORDEN DE DESCENDENCIA POR ID predicado – HotJard

+2

si usa el registro mágico entity.entityID = @ ([[Entity findFirstOrderedByAttribute: @ "entityID" ascendente: NO] entityID] .intValue + 1); – Eldhose

10

Todos NSManagedObjects tienen automáticamente un único NSManagedObjectID. No existe la noción de un atributo personalizado de incremento automático, pero es ciertamente fácil escribir uno usted mismo.

+0

¿Puedo utilizar NSManagedObjectID para obtener ese elemento específico del almacén de datos centrales? – Moshe

+0

Sí, ver http://stackoverflow.com/questions/4720182/core-data-the-primary-key-id-of-a-row-in-the-database/4725959#4725959 – Jano

+0

De hecho, terminé escribiendo mi propio autoincremento usando un agregado. Vea mi respuesta, por favor, si lo desea. +1 para ti. – Moshe

3

Accroding a su Edit2 y Edit3, respuesta siguiente le ayudará a .. Suponga que su campo id como NSNumber tener unsignedInt como identificación.

1) Obtener todos los registros de la entidad correspondiente.

NSError *error = nil; 
NSArray *array = [self fetchAllFileEntity:&error]; 

2) Encuentra el número máximo que pertenece a ese resultado.

NSNumber *maxValue = nil; 
if (array) 
    maxValue = [array valueForKeyPath:@"@max.uniqueId.unsignedIntegerValue"]; 
else 
    maxValue = [NSNumber numberWithUnsignedInteger:0]; 

3) Asignar maxValue + 1 a la nueva entidad

entity.uniqueId = [NSNumber numberWithUnsignedInteger:maxValue.unsignedIntegerValue+1]; 
+2

qué sucede cuando elimino algunas de las filas (filas con el valor máximo) – souvickcse

+1

explique con ex: suponga que tiene 5 medios de fila, el recuento de @max es 5. Ahora eliminaría los medios de la 5ta fila, el recuento máximo es 4 Así que cuando intente agregar nuevo, automáticamente asigne 5 a uno nuevo, es decir, toda la fila si existe en la tabla debe tener un valor único (db local). – Mani

+0

me enfrenta el mismo problema puede cualquiera puede proporcionar la solución adecuada. – Ayaz

1

he llegado con esta solución para dicho problema, espero que va a ser útil para alguien.

AppDelegate *appdelegate = (AppDelegate *) [[UIApplication sharedApplication] delegate]; 

NSManagedObjectContext *context = [appdelegate managedObjectContext]; 

NSError *error = nil; 

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

NSEntityDescription *chatHist = [NSEntityDescription 
            entityForName:@"ChatHistory" inManagedObjectContext:context]; 
[fetchRequest setEntity:chatHist]; 

int chatIdNumber = 0; 

NSArray *fetchedObjects = [context executeFetchRequest:fetchRequest error:&error]; 
if ([fetchedObjects count] > 0) { 
    ChatHistory *chatHistObj = [fetchedObjects objectAtIndex:[fetchedObjects count]-1]; 
    chatIdNumber = [chatHistObj.chatId intValue]; 
} 

chatIdNumber = chatIdNumber+1; 
ChatHistory *chat_History = [NSEntityDescription   insertNewObjectForEntityForName:@"ChatHistory" inManagedObjectContext:context]; 

chat_History.chatId = [NSString stringWithFormat:@"%d",chatIdNumber]; 
Cuestiones relacionadas