NSPredicate搜索1:N - 1:N个实体

时间:2014-04-08 21:55:26

标签: objective-c core-data nspredicate

我有一个名为AcademicYear的实体,其关系为1:N,其实体名为Subject,与实体名为SubjectLanguage的关系为1:N:

AcademicYear< --->>受试对象; --->> SubjectLanguage

我想在AcademicYear上过滤查询结果,以便能够收集已经过参数语言过滤的Subject和SubjectLanguage。

在运行时我将使用这样的表达式:     academicYear.hasSubjects.hasLanguages.subjectName 我想确定它们是由起始查询过滤的特定语言。

我尝试在获取期间使用以下谓词(没有结果):

NSPredicate *predicateLang = [NSPredicate predicateWithFormat:@"ALL hasSubjects.hasLanguages.language like %@", language];

新(更新)

由于Marcus建议我以这种方式更改了获取请求:

NSError *error;
NSString * language = [[NSLocale preferredLanguages] objectAtIndex:0];
NSString * yearString = [NSString stringWithFormat:@"%d",year];
NSPredicate *predicate = [NSPredicate predicateWithFormat:@"belongToAcademicYear.yearId == %@ and ANY hasLanguages.language CONTAINS[cd] %@", yearString, language];



NSFetchRequest *fetchRequest = [[NSFetchRequest alloc] init];
NSEntityDescription *entity = [NSEntityDescription entityForName:@"Subject"
                                          inManagedObjectContext:self.managedObjectContext];

[fetchRequest setEntity:entity];
[fetchRequest setPredicate:predicate];
NSArray *fetchedObjects = [self.managedObjectContext executeFetchRequest:fetchRequest error:&error];
return [self arrayToMutableArrayConverter:fetchedObjects];

}

然后我用以下代码测试了这个解决方案:

NSArray * currentSubjects = [self.coordinator fetchSubjectThatBelongsToAcademicYear:1];
Subject * currentSubject = currentSubjects[0];
NSUInteger count = currentSubject.hasLanguages.count;
XCTAssertEqual(count, 1, @"riscontrati troppi languages. non è stato fatto il filtro su language");

我发现过滤器无法正常工作,我找到了两种语言,而我期待一种语言。我很确定这个问题与谓词有关。

感谢任何支持

亲切的问候

Nicolò

1 个答案:

答案 0 :(得分:0)

你应该稍微扭转一下。不是抓取AcademicYear然后尝试覆盖SubjectLanguage,而是搜索Subject

针对NSFetchRequest构建Subject并将谓词更改为:

NSPredicate *predicate = [NSPredicate predicateWithFormat:@"academicYear == %@ and ANY languages.language CONTAINS[cd] %@", academicYear, language];

一些意见:

  • 你们的关系不应该以“有”开头。它们应该只是academicYearlanguages。单数为一对多,复数为多对。
  • 您的实体SubjectLanguage不应具有名为language的属性。与实体相关的东西可能不那么具有描述性。 name效果很好,因此它是“name”的SubjectLanguage

更新

它完全正确。您找到了具有您要查找的语言和年份的主题。它返回了Subject和 ALL 的关系。由于该主题有多种语言,因此您可以访问所有语言。

谓词是正确的,你的测试是有缺陷的。您的测试应该确保其中一种语言是您正在寻找的语言。