核心数据:使用 To many 关系插入和删除
Posted
技术标签:
【中文标题】核心数据:使用 To many 关系插入和删除【英文标题】:Core data: Insert and delete with To many relationship 【发布时间】: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 个问题。为什么你们的关系不是多对多的?您是否生成了托管对象子类(它们有哪些方法)?您是否尝试过运行任何获取请求? 【参考方案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 . . .
【讨论】:
以上是关于核心数据:使用 To many 关系插入和删除的主要内容,如果未能解决你的问题,请参考以下文章