【问题标题】:Core data: Insert and delete with To many relationship核心数据:使用 To many 关系插入和删除
【发布时间】:2014-02-12 15:27:02
【问题描述】:

我正在使用核心数据制作一个简单的日记应用。

主模型(期刊)将包含标题和正文。 每个条目可以有一个或多个标签。

要插入一个新的(期刊),我只是这样做:

Journal *newJournal  [NSEntityDescription insertNewObjectForEntityForName:@"Journal"
                                             inManagedObjectContext:context];
//Save 

问题一:给条目添加标签的正确方法是什么?

我可以这样做:

Tag *tag1 = [NSEntityDescription insertNewObjectForEntityForName:@"Tag"
                                             inManagedObjectContext:context];
Tag *tag2 = [NSEntityDescription insertNewObjectForEntityForName:@"Tag"
                                             inManagedObjectContext:context];
newJournalEntry.tags = [[NSOrderedSet alloc] initWithObjects:tag1,tag2,nil];
// Save card... 

... 但这将为每个条目创建新标签。我只需要核心数据模型中每个标签的唯一实例。

问题2:如何按标签查询日记条目,例如“获取所有具有fun标签的日记条目”

我还需要获取所有创建的标签并显示它们,例如:“你有 3 个标签:Fun、sport、vacation”

【问题讨论】:

  • 一次提出 1 个问题。为什么你们的关系不是多对多的?您是否生成了托管对象子类(它们有哪些方法)?您是否尝试过运行任何获取请求?

标签: ios objective-c core-data


【解决方案1】:

首先,您需要在 Journal 和 Tag 模型之间建立多对多关系,否则您将无法将同一个 Tag 分配给多个 Journal 条目

答案 1: 在将任何标签分配给日记条目之前,从商店中获取现有标签:

NSFetchRequest *fetchRequest = [[NSFetchRequest alloc] initWithEntityName:@"Tag"];
fetchRequest.predicate = [NSPredicate predicateWithFormat:@"name IN %@", @[@"tag1", @"tag2"]];
NSArray *tags = [moc executeFetchRequest:fetchRequest error:&error];

那么您应该只为缺少的标签创建带有-insertNewObjectForEntityName 的标签。

答案 2:

NSError *error;
NSFetchRequest *fetchRequest = [[NSFetchRequest alloc] initWithEntityName:@"Journal"];
fetchRequest.predicate = [NSPredicate predicateWithFormat:@"tags CONTAINS[cd] %@", @"fun"];
NSArray *journalEntries = [moc executeFetchRequest:fetchRequest error:&error];

您可以在Predicates Programming Guide 中阅读有关谓词的更多信息

【讨论】:

    【解决方案2】:

    答案 1: 您需要在标签和 journalEntry 之间将模型更改为多对多,然后您需要查询模型以查看标签是否已存在。如果他们这样做,那么您只需将它们链接到您的条目实体。

    示例(在伪代码中):

    NSOrderedSet tags = nil;
    //Create and fetch for the tags you are looking for. Then:
    
     if([[FetchedResultController fetchedObjects] count] > 0) {
    
         tags = [[NSOrderedSet alloc] initWithArray:[FetchedResultController fetchedObjects]];
    
     } else {
       //The code you actually have (almost)
       Tag *tag1 = [NSEntityDescription insertNewObjectForEntityForName:@"Tag"
                                             inManagedObjectContext:context];
       Tag *tag2 = [NSEntityDescription insertNewObjectForEntityForName:@"Tag"
                                             inManagedObjectContext:context];
       tags = [[NSOrderedSet alloc] initWithObjects:tag1,tag2,nil];
     }
    
     //Then just set your tags
     newJournalEntry.tags = tags;
    

    答案 2: 一旦你实现了答案一,然后你寻找那些标签,然后只使用与应该是 NSSet 的 journalEntry 的关系(例如:tags.journal)。

    再次伪代码:

    for(Tag *tag in [FetchResultController fetchedObjects]) {
    
           //Get the Journal Entries using:  "tag.journal" 
          NSSet *journalEntriesWithTagRequested = tag.journal;
    
          // Do what you must with journalEntriesWithTagRequested . . .
    
       }
    

    【讨论】:

      猜你喜欢
      • 1970-01-01
      • 2014-01-02
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      • 2013-06-05
      • 1970-01-01
      • 1970-01-01
      相关资源
      最近更新 更多