核心数据的独特属性
是否有可能使核心数据属性唯一,即没有两个MyEntity对象可以具有相同的myAttribute?
我知道如何执行这个编程,但我希望有一种方法来使用xcode中的graphics数据模型编辑器。
我正在使用iPhone 3.1.2 SDK。
每次我在对象上创build一个类方法,只有当另一个不存在时才会创build一个新的实体。
+ (TZUser *)userWithUniqueUserId:(NSString *)uniqueUserId inManagedObjectContext:(NSManagedObjectContext *)context { TZUser *user = nil; NSFetchRequest *request = [[NSFetchRequest alloc] init]; request.entity = [NSEntityDescription entityForName:@"TZUser" inManagedObjectContext:context]; request.predicate = [NSPredicate predicateWithFormat:@"objectId = %@", uniqueUserId]; NSError *executeFetchError = nil; user = [[context executeFetchRequest:request error:&executeFetchError] lastObject]; if (executeFetchError) { NSLog(@"[%@, %@] error looking up user with id: %i with error: %@", NSStringFromClass([self class]), NSStringFromSelector(_cmd), [uniqueUserId intValue], [executeFetchError localizedDescription]); } else if (!user) { user = [NSEntityDescription insertNewObjectForEntityForName:@"TZUser" inManagedObjectContext:context]; } return user; }
我已经决定使用validate<key>:error:
方法来检查是否已经有一个具有特定值<key>
的托pipe对象。 如果是这种情况,则会出现错误。
例如:
- (BOOL)validateMyAttribute:(id *)值错误:(NSError **)error { //如果已经有一个带有myAtribute值的对象,则返回NO }
感谢Martin Cote的投入。
从IOS 9有一个新的方法来处理独特的约束。
您可以在数据模型中定义唯一的属性。
您需要设置托pipe上下文合并策略“合并策略单例对象,以定义在保存操作期间处理冲突的标准方式”NSErrorMergePolicy是默认值。如果存在任何合并冲突,则此策略会导致保存失败。
- (NSManagedObjectContext *)managedObjectContext { // Returns the managed object context for the application (which is already bound to the persistent store coordinator for the application.) if (_managedObjectContext != nil) { return _managedObjectContext; } NSPersistentStoreCoordinator *coordinator = [self persistentStoreCoordinator]; if (!coordinator) { return nil; } _managedObjectContext = [[NSManagedObjectContext alloc] initWithConcurrencyType:NSMainQueueConcurrencyType]; [_managedObjectContext setPersistentStoreCoordinator:coordinator]; [_managedObjectContext setMergePolicy:NSOverwriteMergePolicy]; return _managedObjectContext; }
Apple Ducumentation Merge Policy中讨论了各种选项
这里很好地回答了Zachary Orr的答案
他也好心地创build了一个博客和示例代码。
示例代码
博客文章
最具挑战性的部分是获取数据模型属性可编辑。秘密是左键单击,然后右键单击,然后单击+符号添加约束。
您可以覆盖setMyAttribute
方法(使用类别),并确保唯一性,虽然这可能是昂贵的:
- (void)setMyAttribute:(id)value { NSArray *objects = [self fetchObjectsWithMyValueEqualTo:value]; if( [objects count] > 0 ) // ... throw some exception [self setValue:value forKey:@"myAttribute"]; }
如果您想确保每个MyEntity
实例都具有不同的myAttribute
值,那么可以使用NSManagedObject
对象的objectID
。
我真的很喜欢@DoozMen的做法! 我认为这是做我需要做的最简单的方法。
这是我把它安装到我的项目中的方式:
下面的代码循环绘制一个相当长的tableView,为每个表行保存一个对象,并为每个对象设置各种对象属性,比如UISwitch
状态和其他东西:如果具有某个标记的行的对象不存在在DB内部,它创build它。
NSFetchRequest *request = [[NSFetchRequest alloc] init]; request.entity = [NSEntityDescription entityForName:@"Obiettivo" inManagedObjectContext:self.managedObjectContext]; request.predicate = [NSPredicate predicateWithFormat:@"obiettivoID = %d", obTag]; NSError *executeFetchError = nil; results = [[self.managedObjectContext executeFetchRequest:request error:&executeFetchError] lastObject]; if (executeFetchError) { NSLog(@"[%@, %@] error looking up for tag: %i with error: %@", NSStringFromClass([self class]), NSStringFromSelector(_cmd), obTag, [executeFetchError localizedDescription]); } else if (!results) { if (obbCD == nil) { NSEntityDescription *ent = [NSEntityDescription entityForName:@"Obiettivo" inManagedObjectContext:self.managedObjectContext]; obbCD = [[Obiettivo alloc] initWithEntity:ent insertIntoManagedObjectContext:self.managedObjectContext]; } //set the property that has to be unique.. obbCD.obiettivoID = [NSNumber numberWithUnsignedInt:obTag]; [self.managedObjectContext insertObject:obbCD]; NSError *saveError = nil; [self.managedObjectContext save:&saveError]; NSLog(@"added with ID: %@", obbCD.obiettivoID); obbCD = nil; } results = nil;
看一下苹果文档的属性间validation。 它描述了如何在查询整个数据库的同时validation特定的插入或更新操作。