核心数据,尝试使用NSPredicate过滤多个关系集,但获得“在这里不允许的许多键”错误 [英] Core Data, try to use NSPredicate to filter a toMany relationship set but get the "to-many key not allowed here" error

查看:176
本文介绍了核心数据,尝试使用NSPredicate过滤多个关系集,但获得“在这里不允许的许多键”错误的处理方法,对大家解决问题具有一定的参考价值,需要的朋友们下面随着小编来一起学习吧!

问题描述

以下是我的模型:
http://www.girardet.ch/ model.png



我的目标是使用这些标准检索所有报价:




  • 属于特定主题:主题的名称属性

  • 按相关顺序排序

  • 的作者)



以下是我的代码:

 code> NSFetchRequest * fetchRequest = [[NSFetchRequest alloc] init]; 
NSEntityDescription * entity = [NSEntityDescription entityForName:@ThemeEntriesinManagedObjectContext:_context];
[fetchRequest setEntity:entity];

NSSortDescriptor * sortDescriptor1 = [[NSSortDescriptor alloc] initWithKey:@relevancyascending:NO];
NSArray * sortDescriptors = [[NSArray alloc] initWithObjects:sortDescriptor1,nil];
[fetchRequest setSortDescriptors:sortDescriptors];

// predictate - filter
NSPredicate * predicate = [NSPredicate predicateWithFormat:@theme.name_en =%@ AND quotes.author.alias =%@,@mytheme myauthor];

[fetchRequest setPredicate:predicate];





如果我改用这个谓词



<$> p $ p> NSPredicate * predicate = [NSPredicate predicateWithFormat:@theme.name_en =%@,@mytheme];

它工作得很好,我可以循环的 ThemeEntries ,我得到并得到所有的报价...但它没有过滤



我可以通过作者过滤什么?

解决方案

p>你的问题是你的一个keypath的关系是一对多,多对多,并且谓词不知道哪个具体对象与哪个对象。



您有 ThemeEntities< < - >> Quotes 这是在每一端产生一个集合。 quotes.author.alias keypath说一组引号实例,每个链接到作者实例,它们又具有别名属性。谓词不能处理集合。



您需要使用子查询来跳转到多个键。子查询本质上是一个嵌套谓词,用于搜索集合并返回与嵌套谓词匹配的另一组对象。子查询记录不良,但它们的格式如下:

  SUBQUERY(collectionName,$ collectionElementVariable,expression-with- $ collectionElementVariable)

在这种情况下,您正在查找与匹配提供的字符串的别名具有作者关系的任何报价实例。您的谓词需要如下:

  @theme.name_en =%@ AND(0!= SUBQUERY eachQuote,$ eachQuote.author.alias =%@)。@ count),@mytheme,@myauthor


b $ b

子查询说,在引号集中,取每个引号对象并测试其作者关系对象是否具有与'myauthor'匹配的别名属性。计算具有该匹配的引号对象的数量如果数字是非零,返回TRUE。



每当您跨越一对多关系走过关键字时,您就需要使用子查询。


Here is the model I have: http://www.girardet.ch/model.png

My goal is to retrieve all the Quotes with these criterias:

  • belong to a specific theme : the name_en attribute of Themes
  • order by relevancy
  • filtered by Authors (with the alias attribute of Authors)

Here is my code:

NSFetchRequest *fetchRequest = [[NSFetchRequest alloc] init];
NSEntityDescription *entity = [NSEntityDescription entityForName:@"ThemeEntries" inManagedObjectContext:_context];
[fetchRequest setEntity:entity];

NSSortDescriptor *sortDescriptor1 = [[NSSortDescriptor alloc] initWithKey:@"relevancy" ascending:NO];
NSArray *sortDescriptors = [[NSArray alloc] initWithObjects:sortDescriptor1, nil];
[fetchRequest setSortDescriptors:sortDescriptors];

// predictate - filter
NSPredicate *predicate = [NSPredicate predicateWithFormat:@"theme.name_en=%@ AND quotes.author.alias=%@",@"mytheme", @"myauthor"];

[fetchRequest setPredicate:predicate];

I get the "to-many key not allowed here" error.

If I instead use this predicate

NSPredicate *predicate = [NSPredicate predicateWithFormat:@"theme.name_en=%@, @"mytheme"];

it works well and I can loop over the ThemeEntries that I get and get all my quotes... But it's not filtered by authors.

What can I do to filter by Authors?

解决方案

Your problem is that the relationship of one of you keypath is a to-many, to-many and the predicate does not know which particular object goes with which.

You have ThemeEntities<<-->>Quotes which is produces a set at each end. The quotes.author.alias keypath says "a set of quotes instances, each linked to author instances which in turn has an alias attribute." The predicate cannot process the set.

You need to use a subquery to jump a to-many keypath. The subquery is essentially a nested predicate which searches a set and returns another set of objects matching the nested predicate. Subqueries are poorly documented but they have the form:

SUBQUERY(collectionName,$collectionElementVariable,expression-with-$collectionElementVariable)

In this case, you are looking for any quote instances that has a author relationship with an alias matching the supplied string. Your predicate would need to look like:

@"theme.name_en=%@ AND (0!=SUBQUERY(quotes,$eachQuote,$eachQuote.author.alias=%@).@count)",@"mytheme", @"myauthor"

The subquery says, "Of the set of quotes, take each quote object and test if its author relationship object has an alias attribute matching 'myauthor'. Count the number of quote objects with that match. If the number is non-zero, return TRUE."

You need to use subqueries whenever you walk a keypath across a to-many relationship.

这篇关于核心数据,尝试使用NSPredicate过滤多个关系集,但获得“在这里不允许的许多键”错误的文章就介绍到这了,希望我们推荐的答案对大家有所帮助,也希望大家多多支持IT屋!

查看全文
登录 关闭
扫码关注1秒登录
发送“验证码”获取 | 15天全站免登陆