代码之家  ›  专栏  ›  技术社区  ›  robinjam

核心数据唯一属性

  •  35
  • robinjam  · 技术社区  · 15 年前

    是否可以使核心数据属性唯一,即没有两个MyEntity对象可以具有相同的MyAttribute?

    我知道如何通过编程实现这一点,但我希望有一种方法可以使用Xcode中的图形数据模型编辑器来实现这一点。

    我使用的是iPhone3.1.2sdk。

    6 回复  |  直到 9 年前
        1
  •  28
  •   Joony s3rro    12 年前

    每次我在对象上创建时,我都会执行一个类方法,该方法只在另一个实体不存在时创建一个新实体。

    + (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;
    }
    
        2
  •  12
  •   robinjam    15 年前

    我决定用 validate<key>:error: 方法检查是否已存在具有特定值的托管对象 <key> . 如果是这种情况,则会引发错误。

    例如:

    - (BOOL)validateMyAttribute:(id *)value error:(NSError **)error {
        // Return NO if there is already an object with a myAtribute of value
    }

    感谢Martin Cote的投入。

        3
  •  9
  •   Community CDub    8 年前

    从iOS 9开始,有了一种新的方法来处理独特的约束。

    您可以在数据模型中定义唯一的属性。

    您需要设置托管上下文合并策略“merge policy singleton objects that define standard way to handle conflicts during a save operation”nserrormergepolicy is the default,this policy causes a save to fail if there are any merge conflicts.

    —(nsmanagedObjectContext*)managedObjectContext{
    //返回应用程序的托管对象上下文(该上下文已绑定到应用程序的持久存储协调器)。
    如果(\u managedObjectContext!= nIL){
    返回ManagedObjectContext;
    }
    
    nsPersistentStoreCoordinator*Coordinator=[自我PersistentStoreCoordinator];
    如果(!)协调器){
    返回零;
    }
    _ managedObjectContext=[[nsManagedObjectContext alloc]initWithConcurrencyType:nsMainQueueConcurrencyType];
    [\u managedObjectContext setPersistentStoreCoordinator:Coordinator];
    [\u managedObjectContext setMergePolicy:nsOverwriteMergePolicy];
    返回ManagedObjectContext;
    }
    < /代码> 
    
    

    各种选项在apple文档合并策略中讨论。

    这里的回答很好 Zachary Orr的答案

    他还友好地创建了一个blogpost和示例代码。

    示例代码

    blog post

    最具挑战性的部分是使数据模型属性可编辑。秘诀是在单击+符号添加约束后,单击左键,然后单击右键。

    d context merge policy“定义在保存操作期间处理冲突的标准方法的合并策略singleton对象”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's Answer

    他还友好地创建了一个blogpost和示例代码。

    Sample Code

    Blog Post

    最具挑战性的部分是使数据模型属性可编辑。秘诀是在单击+符号添加约束后,左键单击,然后右键单击。

    enter image description here

        4
  •  3
  •   Martin Cote    15 年前

    您可以覆盖 setMyAttribute 方法(使用类别)并确保唯一性,尽管这可能很昂贵:

    - (void)setMyAttribute:(id)value
    {
       NSArray *objects = [self fetchObjectsWithMyValueEqualTo:value];
       if( [objects count] > 0 )  // ... throw some exception
       [self setValue:value forKey:@"myAttribute"];
    }
    

    如果你想确保 MyEntity 实例具有不同的 myAttribute 值,您可以使用 objectID NSManagedObject 这件事的对象。

        5
  •  0
  •   Paolo83    12 年前

    我真的很喜欢@doozmen的方法!你说什么? 我认为这是做我需要做的事情最简单的方法。

    这就是我将其融入项目的方式:

    以下代码在绘制一个相当长的表视图、为每一行保存一个对象并为每一行设置不同的对象属性时循环,例如 UISwitch 状态和其他事项:如果数据库中不存在具有特定标记的行的对象,则会创建该对象。

    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;
    
        6
  •  0
  •   Litherum    9 年前

    看看苹果 documentation 用于属性间验证。它描述了如何在查询整个数据库的同时验证特定的插入或更新操作。