对许多实体和实体关系进行过滤的核心数据提取

Posted

技术标签:

【中文标题】对许多实体和实体关系进行过滤的核心数据提取【英文标题】:Core Data Fetch with filter on entity and entities relationship, to many 【发布时间】:2013-05-16 19:01:49 【问题描述】:

我需要有关过滤子项和父项具有多对多关系的子项的获取请求的帮助。我发现的所有示例都是针对一对多关系的。

播放列表可以通过歌曲关系包含许多歌曲 歌曲可以通过播放列表关系出现在许多播放列表中。 这些关系是互逆的。

我正在尝试查找播放列表 id = 1 且歌曲名称以“a”开头的歌曲对象的过滤列表。

我尝试了很多东西,不想为所有这些都包含代码,但它们包括尝试子查询、获取播放列表然后尝试在其歌曲 nsset(转换为 nsarray)上运行 nsprediate,以及一些其他的东西。

这是我认为最接近我需要的东西。

NSEntityDescription *entityDescription = [NSEntityDescription entityForName:@"Song" inManagedObjectContext:self.playlistRKCoreDataManager.managedObjectStore.mainQueueManagedObjectContext];

NSFetchRequest *request = [[NSFetchRequest alloc] init];
NSString *queryStr = [NSString stringWithFormat:@"playlists.playlist_id == \"%@\" AND name BEGINSWITH[c] \"%@\"", playlistID, songQuery];
[request setPredicate:[NSPredicate predicateWithFormat: queryStr]];
[request setEntity:entityDescription];

【问题讨论】:

【参考方案1】:

您不应该使用stringWithFormat 来构建谓词。如果搜索字符串(playlistID、songQuery)包含特殊字符,特别是如果它们包含引号 ",这将失败。

更好更安全的方法是

NSPredicate *predicate = [NSPredicate predicateWithFormat:@"ANY playlists.playlist_id =[cd] %@ AND name BEGINSWITH[c] %@", playlistID, songQuery];
[request setPredicate:predicate];

因为predicateWithFormat 正确处理了所有这些情况。

(这与人们应该使用“准备好的语句”进行 SQL 查询的原因大致相同,即使这样:http://xkcd.com/327/ 可能不会在 Core Data 中发生 :-)

【讨论】:

我实际上需要用户能够使用引号进行搜索,因为某些歌曲名称以引号开头,所以谢谢,这很好用。【参考方案2】:

当然,经过数小时的尝试,我在发布此问题几分钟后找到了自己的答案。

NSString *queryStr = [NSString stringWithFormat:@"ANY playlists.playlist_id =[cd] \"%@\" AND name BEGINSWITH[c] \"%@\"", playlistID, songQuery];
[request setPredicate:[NSPredicate predicateWithFormat: queryStr]];

【讨论】:

以上是关于对许多实体和实体关系进行过滤的核心数据提取的主要内容,如果未能解决你的问题,请参考以下文章

按祖父母实体关系过滤核心数据

如何创建一个基于父关系过滤核心数据对象的 NSFetchRequest?

在 Core Data 中获取过滤的关系

使用 NSPredicate 过滤核心属性和实体

使用基于属性的过滤子元素集获取核心数据实体

如何根据多对关系集是不是包含特定值使用 NSPredicate 进行过滤