核心数据:返回另一个实体的对象的谓词

Posted

技术标签:

【中文标题】核心数据:返回另一个实体的对象的谓词【英文标题】:Core Data: Predicate that Returns Objects of Another Entity 【发布时间】:2011-07-06 09:15:43 【问题描述】:

我的数据模型中有两个实体:DetailsLookup。我需要找到与具有特定属性值的特定Lookup 对象相关的所有Details 对象,然后通过获取的结果控制器返回这些Details 对象。

我的 NSManagedObjectSubclasses:

@interface Details : NSManagedObject 
@privateI 

@property (nonatomic, retain) NSString * owner;
@property (nonatomic, retain) NSString * introduction;
@property (nonatomic, retain) NSString * id;
@property (nonatomic, retain) NSString * title;
@property (nonatomic, retain) NSString * created;
@property (nonatomic, retain) NSString * modified;
@property (nonatomic, retain) NSNumber * type;
@property (nonatomic, retain) NSString * desc;


@interface Lookup : NSManagedObject 
@private

@property (nonatomic, retain) NSDate * search_date;
@property (nonatomic, retain) NSString * search_phrase;
@property (nonatomic, retain) NSSet* searchResults;

我需要根据其search_phrase 属性找到一个Lookup 对象,然后获取所有相关的Details 对象并在获取的结果控制器中返回这些对象。

我想我必须先搜索Lookup 对象,然后遍历 Detail 对象的 NSSet,但我不知道如何在 NSFetchedResultsController 中返回这些对象。

我试过了:

NSPredicate *predicate =[NSPredicate predicateWithFormat:@"search_phrase = %@", self.searchPhrase];

NSFetchRequest *fetchRequest = [[NSFetchRequest alloc] init];

fetchRequest.predicate = predicate;

NSEntityDescription *entity = [NSEntityDescription entityForName:@"Lookup" inManagedObjectContext:self.context];

[fetchRequest setEntity:entity];

NSSortDescriptor *sort = [[NSSortDescriptor alloc] initWithKey:@"search_phrase" ascending:NO];

[fetchRequest setSortDescriptors:[NSArray arrayWithObject:sort]];

NSFetchedResultsController *theFetchedResultsController = [[NSFetchedResultsController alloc] initWithFetchRequest:fetchRequest managedObjectContext:self.context sectionNameKeyPath:nil cacheName:@"Searches"];

我有一个找到正确的Lookup 对象的请求,但我不知道如何从获取的结果控制器中获取相关的Detail 对象。

【问题讨论】:

您的原始问题因不清楚且不完整而被否决。任何人都很难弄清楚你需要什么。我已使用附加信息对其进行了编辑,以提出更有用的问题。 啊,我明白了,对不起,我下次会努力让自己更清楚。 【参考方案1】:

首先,DetailsLookup 之间没有定义互惠关系,而只是 LookupDetails 的单向关系。您需要向从Detail 运行到Lookup 的数据模型实体添加一个关系,并设置它具有Lookup.searchResults 的倒数,并且您的Detail 类需要类似的属性:

@property (nonAtomic,retain) Lookup *lookup;

具有互惠关系可以让您找到以Lookup 对象开头的Detail 对象,并让您找到以Detail 对象开头的Lookup 对象。

如果您希望 tableview 显示 Detail 对象的列表,那么您需要配置 fetched results controller 的 fetch request 以针对 Detail 实体进行 fetch。根据经验,您始终将获取请求实体设置为您希望在表格视图中显示其对象的实体。

谓词同样将针对Detail 实体运行,因此您需要一个针对以Detail 实体的属性开头的键路径进行评估的谓词。在这种情况下,我们希望所有Details 对象的相关Lookup 对象具有等于提供值的search_phase 属性。所以:

NSPredicate *p=[NSPredicate predicateWithFormat:@"lookup.search_phrase==%@", self.searchPhrase];

现在设置您的获取请求:

  NSFetchRequest *fetch=[[NSFetchRequest alloc] init];
  NSEntityDescription *detailsEntity=[NSEntityDescription entityForName:@"Details" inManagedObjectContext:self.context];
  [fetch setEntity:detailsEntity];
  [fetch setPredicate:p];
  //.. set up a sort however you want the details to appear in the tableview

把这个 fetch 给你的 NSFetchedResultsController,它会返回你正在寻找的 Detail 对象。

总结:

始终在数据模型中使用互惠关系,以便您拥有灵活性。 使用获取结果控制器时,将获取请求的实体设置为您希望其对象出现在表格视图中的实体。

【讨论】:

一个很好的答案让我很清楚......谢谢!我会着手实施这个并让你知道结果,再次感谢【参考方案2】:

如果没有您的一些示例代码甚至实际关系,很难回答,但这里是:

对表 A 执行初始筛选。这会为您提供一组包含多个对象的结果。 使用您的过滤器和AND #Put name of the relationship here# IN (the results of 1) 查询表 B

不过,还有一点需要补充,您应该停止将核心数据视为关系数据库。这是一个对象图。核心数据可能会也可能不会使用不同的表来存储数据。您应该关心的是对象及其关系。

如果我理解正确,您并不是真的想要一对多,而是多对多。 然后,您将能够使用对 B 对象的查询同时执行两个查询:

A.your.a.query == 'What you're querying for' AND your.b.query == here

【讨论】:

我试过这个:predicate = [NSPredicate predicateWithFormat:@"type = %@ AND searchResults IN %@", self.resource, lsrm.searchResults];但我收到一条错误消息,指出无效谓词:nil RHS 对此一点运气都没有,有人想给我扔一根骨头吗? NSPredicate *predicate = [NSPredicate predicateWithFormat:@"type = %@ AND searchResults IN %@", self.resource, lsrm.searchResults] 其中 lsrm.searchResults 是来自 Lookup 对象的 NSSet。现在我收到一个错误说明:原因:'未实现的谓词 SQL 生成 NSPredicate *predicate = [NSPredicate predicateWithFormat:@"type = %@ AND SELF IN %@", self.resource, lsrm.searchResults];就是这样。我从一位同事那里找到了这个答案,但接受了你的答案,因为它为我指明了正确的方向;-)

以上是关于核心数据:返回另一个实体的对象的谓词的主要内容,如果未能解决你的问题,请参考以下文章

核心数据获取请求不返回不同的结果

在 DidSelect 上,如何返回整个核心数据记录? (迅速)

核心数据提取返回意外结果

复合谓词不返回结果

子查询谓词核心数据

使用 NSPredicate 遍历多个 Core Data 对象