2011-06-16 13 views
6

Pracuję z kilkoma typami NSManagedObject z kilkoma relacjami. Jak mogę nakazać Core Data automatyczne wypełnianie ID obiektów? Szukam kodu indeksu w SQL, aby żadne dwa wystąpienia danego obiektu nie miały takiego samego identyfikatora.Auto-inkrementowany identyfikator obiektu w danych podstawowych?

Edit:

Chciałbym dla wszystkich moich przedmiotów „Konto” mają unikalne identyfikatory na nich. Właśnie dodawałem jeden do `countForFetchRequest, ale zdałem sobie sprawę, że podczas usuwania drugiego do ostatniego obiektu, a następnie dodawania jednego, dwa ostatnie obiekty mają teraz te same identyfikatory.

Jak mogę zapewnić, że dana wartość ma unikalną wartość dla wszystkich wystąpień mojego "konta" NSManagedObject?

EDIT2:

muszę mieć oddzielny identyfikator dla celów sortowania.

Odpowiedz

4

Sposób, w jaki to rozwiązałem, dotyczy agregatów danych podstawowych. Właściwie to sam przypisuję ID.

Zasadniczo, wyszukuję dane podstawowe dla wszystkich identyfikatorów jednostek mojej jednostki, a następnie iteruję za ich pomocą. Jeśli znajdę identyfikator wyższy niż bieżący tymczasowy, to tymczasowy identyfikator będzie wyższy o jeden wyższy od zagregowanego. Kiedy skończę, automatycznie otrzymuję identyfikator wyższy od najwyższego na liście. Jedyną wadą, którą widzę z tym, jest brak identyfikatora. (Wierzę, że istnieje prosta poprawka do tego jak dobrze.)

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

Nie musisz pobierać wszystkich wierszy - tylko ostatni przy sortowaniu malejącym według predykatora id – HotJard

+2

, jeśli używasz magicznej jednostki entity.entityID = @ ([Entity findFirstOrderedByAttribute: @ "entityID" rosnąco: NO] entityID] .intWartość + 1); – Eldhose

10

Wszystkie NSManagedObjects automatycznie mają unikalny NSManagedObjectID. Nie ma pojęcia o niestandardowym atrybucie auto-inkrementacji, ale z pewnością łatwo jest go napisać samemu.

+0

Czy mogę użyć identyfikatora NSManagedObjectID do pobrania tego konkretnego elementu ze składnicy danych podstawowych? – Moshe

+0

Tak, zobacz http://stackoverflow.com/questions/4720182/core-data-the-primary-key-id-of-a--w-the-database/4725959#4725959 – Jano

+0

Skończyło się na tym, że napisałem własne auto-inkrementacji za pomocą agregatu. Zobacz moją odpowiedź, jeśli chcesz. +1 dla ciebie. – Moshe

3

accroding do Edit2 i Edit3 po odpowiedzi pomogą Ci .. Załóżmy swoje pole id jako NSNumber mający unsignedInt jako ID.

1) Pobierz wszystkie rekordy dla odpowiedniego obiektu.

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

2) Znajdź maksymalną liczbę należącą do tego wyniku.

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

3) Przypisywanie MAXVALUE + 1 do nowego podmiotu

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

co się stanie, gdy usuwam niektóre wiersze (wiersze z wartością maksymalną) – souvickcse

+1

wyjaśnij na przykład: Załóżmy, że masz 5 wierszy oznacza, @maks liczba to 5. Teraz usuniesz 5 wiersz oznacza, maksymalna liczba to 4 Jeśli więc spróbujesz dodać nowe, automatycznie przypisz 5 do nowego, to znaczy, że cały wiersz, jeśli istnieje w tabeli, powinien mieć unikalną wartość (lokalny db). – Mani

+0

Mam do czynienia z tym samym problemem, każdy może zapewnić odpowiednie rozwiązanie. – Ayaz

1

I mają pochodzić z tego rozwiązania dla tego problemu, mam nadzieję, że to będzie pomocne dla kogoś.

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]; 
Powiązane problemy