问题
I am working with several NSManagedObject
types with several relationships. How can I tell Core Data to automatically populate object IDs for me? I'm looking for something like an index key in SQL, so that no two instances of a given object are allowed to have the same ID.
Edit:
I'd like for all of my "Account" objects to have unique IDs on them. I was just adding one to the `countForFetchRequest, but I realized that when deleting the second to last object and then adding one, the last two objects now have the same IDs.
How can I ensure that a given value has a unique value for all instances of my "Account" NSManagedObject?
EDIT2:
I need to have a separate ID for sorting purposes.
回答1:
All NSManagedObjects
automatically have a unique NSManagedObjectID
. There is no notion of a custom auto-incrementing attribute, but it's certainly easy to write one yourself.
回答2:
The way I resolved this is with Core Data aggregates. I actually end up assigning the ID myself.
Essentially, I query Core Data for all of the entity IDs of my entity and then iterate through them. If I find an ID which is higher than the current temporary one, I make the temporary ID higher one higher than the aggregated one. When I'm done, I automatically have an ID which is higher than the highest one in the list. The only flaw I see with this is if there is a missing ID. (I believe that there is a simple fix for this as well.)
//
// 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 ...
//
回答3:
Accroding to your EDIT2 and Edit3, following answer will help you.. Assume your id field as NSNumber having unsignedInt as ID.
1) Fetch all records for corresponding entity.
NSError *error = nil;
NSArray *array = [self fetchAllFileEntity:&error];
2) Find maximum number belonging to that result.
NSNumber *maxValue = nil;
if (array)
maxValue = [array valueForKeyPath:@"@max.uniqueId.unsignedIntegerValue"];
else
maxValue = [NSNumber numberWithUnsignedInteger:0];
3) Assign maxValue+1 to your new entity
entity.uniqueId = [NSNumber numberWithUnsignedInteger:maxValue.unsignedIntegerValue+1];
回答4:
I have come up with this solution for the said problem, hope it's gonna be helpful for some one.
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];
来源:https://stackoverflow.com/questions/6376713/auto-incremented-object-id-in-core-data