2011-06-16 15 views
6

Sto lavorando con diversi tipi NSManagedObject con diverse relazioni. Come posso comunicare a Core Data la compilazione automatica degli ID oggetto per me? Sto cercando qualcosa come una chiave indice in SQL, in modo che nessuna istanza di un dato oggetto possa avere lo stesso ID.ID oggetto autoincrementato nei dati principali?

Edit:

Mi piacerebbe per tutti i miei oggetti "account" di avere ID univoci su di loro. Stavo solo aggiungendo uno al `countForFetchRequest, ma mi sono reso conto che quando si elimina il penultimo oggetto e quindi ne aggiungi uno, gli ultimi due oggetti ora hanno gli stessi ID.

Come posso garantire che un determinato valore abbia un valore univoco per tutte le istanze del mio "Account" NSManagedObject?

EDIT2:

ho bisogno di avere un ID separato per fini di smistamento.

risposta

4

Il modo in cui ho risolto questo problema è con gli aggregati di Core Data. In realtà finisco per assegnare l'ID da solo.

In sostanza, interrogo i dati di base per tutti gli ID entità della mia entità e quindi iterato attraverso di essi. Se trovo un ID che è superiore a quello temporaneo corrente, renderò l'ID temporaneo più alto di uno superiore rispetto a quello aggregato. Quando ho finito, ho automaticamente un ID che è più alto di quello più alto nella lista. L'unico difetto che vedo è se c'è un ID mancante. (Credo che ci sia una semplice correzione per questo pure.)

// 
// 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

Non è necessario recuperare tutte le righe - solo l'ultimo usando l'ordinamento decrescente per ID predicato – HotJard

+2

se si utilizza il record magico entity.entityID = @ ([[Entità findFirstOrderedByAttribute: @ "entityID" crescente: NO] entityID] .intValue + 1); – Eldhose

10

Tutti NSManagedObjects dispongono automaticamente di un NSManagedObjectID unico. Non c'è idea di un attributo autoincrementante personalizzato, ma è certamente facile scriverne uno da solo.

+0

Posso utilizzare NSManagedObjectID per prelevare quell'elemento specifico dall'archivio Dati principali? – Moshe

+0

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

+0

In realtà ho finito per scrivere il mio proprio incremento automatico utilizzando un aggregato. Vedi la mia risposta per favore, se vuoi. +1 per te. – Moshe

3

Accroding al vostro EDIT2 e Edit3, seguente risposta vi aiuterà a .. Si supponga il vostro campo id come NSNumber avendo unsignedInt come ID.

1) Recupera tutti i record per l'entità corrispondente.

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

2) Trovare numero massimo appartenente a tale risultato.

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

3) Assegnare maxValue + 1 alla tua nuova entità

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

cosa succede quando elimino alcune delle righe (righe con il valore massimo) – souvickcse

+1

spiega con ex: Supponiamo che tu abbia 5 righe significa, il conteggio @max è 5. Ora cancelleresti la quinta riga, il conteggio massimo è 4 Quindi, quando provi ad aggiungere nuovi, assegna automaticamente 5 a uno nuovo, ovvero, tutte le righe se presenti nella tabella devono avere un valore univoco (db locale). – Mani

+0

sto affrontando lo stesso problema può chiunque può fornire una soluzione adeguata. – Ayaz

1

Sono venuto su con questa soluzione per il suddetto problema, la speranza sta andando essere utile per qualcuno.

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]; 
Problemi correlati