使用Core Data获取数据

时间:2012-12-29 06:55:07

标签: objective-c ios core-data nspredicate nsfetchrequest

我在互联网上搜索了很多但找不到我要找的东西。

我有这个模型,它可能是很多用户。所以我有一个名为User的实体。用户有NSSet条记录。我想从给定的用户那里获取记录。我试图像这样做,但它仍然返回所有用户的记录。

NSManagedObjectContext *context = _backgroundContext;
NSFetchRequest *fetchRequest = [[NSFetchRequest alloc] init];
NSEntityDescription *entity = [NSEntityDescription entityForName:@"Record"
                                                  inManagedObjectContext:context];

NSPredicate *predicate = [NSPredicate predicateWithFormat:@"(date >= %@)",date];
NSPredicate *predicate1 = [NSPredicate predicateWithFormat:@"User = %@",currentUser];

NSPredicate *predicates = [NSCompoundPredicate andPredicateWithSubpredicates:[NSArray arrayWithObjects:predicate,predicate1, nil]];
[fetchRequest setPredicate:predicates];

[fetchRequest setPredicate:predicate];
[fetchRequest setEntity:entity];
NSError *error = nil;
NSArray *fetchedObjects = [context executeFetchRequest:fetchRequest error:&error];

我知道这应该不难,但我找不到它是什么,我希望你们中的一些人可以提供帮助。提前谢谢!

修改

正如我所说,我有一个实体User,其中包含:

NSString name,
int age,
NSSet records, ...

Record有自己的属性,例如:

NSDate date,
NSString name,
NSString event, 
...

我想形成一个获取请求来获取来自特定用户的记录。我不知道该怎么做,因为我收到了每个用户的所有记录。

记录具有To-Many关系。我可以获得像currentUser.records这样的记录,但我无法让用户使用record.User。

4 个答案:

答案 0 :(得分:2)

我假设您的模型看起来大致如此,即记录关系具有称为user的反向关系:

User-Record model

重要的是这种关系是反向关系,否则核心数据不会自动维护它。然后,您可以在给定日期之后/之后查询给定用户的所有记录,如下所示:

NSFetchRequest *fetchRequest = [[NSFetchRequest alloc] initWithEntityName:@"Record"];
fetchRequest.predicate = [NSPredicate predicateWithFormat:@"user = %@ AND (date >= %@)", currentUser, date];

NSError *error = nil;
NSArray *records = [_backgroundContext executeFetchRequest:fetchRequest error:&error];

NSLog(@"records: %@", records);

我已经将您的代码重写为更紧凑,但重要的变化是,这将一次创建查询。

答案 1 :(得分:1)

错误在于:

[fetchRequest setPredicate:predicates];
[fetchRequest setPredicate:predicate];

设置复合谓词后,用单独的date谓词覆盖它。您可能想要删除第二行。

编辑:获取请求要求您定义了从userRecord的反向关系User,并在此处使用此关系的确切名称谓词。

另一种解决方案是使用UserRecord之间的“转发”关系并过滤结果:

NSSet *records = [currentUser.records filteredSetUsingPredicate:predicates];

或者,如果您更喜欢数组

NSArray *records = [[currentUser.records allObjects] filteredArrayUsingPredicate:predicates];

答案 2 :(得分:1)

正如Martin R所说,你正在取代你的谓词。 正如他所提到的,用户属性应该是小写的,因为我很确定核心数据会强制执行此操作。如果您尝试使用大写字母创建关系,它应该会给您一个错误,所以请尝试

NSPredicate *predicate1 = [NSPredicate predicateWithFormat:@"user = %@",currentUser];

代替。显然,如果你的模型没有为用户定义属性,那么它也无法工作,你需要将它改为你的模型实际拥有的任何东西,但这应该是有效的。

修改

尝试在模型中添加反向关系。所以你的结构看起来像:

用户

NSString name,
int age,
NSSet records, ...

<强>记录

NSDate date,
NSString name,
NSString event, 
User user,
...

然后,每次创建新记录,以及将记录添加到用户记录集时,也要在记录对象上设置用户。这将使得获取记录变得更加容易,并且它还允许核心数据保持数据完整性:

"You should typically model relationships in both directions, and specify the inverse 
relationships appropriately. Core Data uses this information to ensure the consistency of the 
object graph if a change is made"

(Core Data programming guide)

设置完成后,只需拨打record.user

即可轻松获取记录用户

如果多个用户需要多个记录,则只需将关系设置为多对多关系,并将User user属性更改为NSSet user

如果您不想更改模型,那么我对您的问题有点困惑。你说你想获得给定用户的记录?如果是这样,那么为什么不简单地调用user.records,因为已经定义了这种关系?没有必要为此提供整个获取请求,让核心数据为您管理那个。

如果您希望根据日期过滤生成的记录,则可以自己将谓词应用于结果数组,而无需获取提取请求。

答案 3 :(得分:0)

我找到了我搜索过的内容!我只需要使用这个

形成一个谓词
NSPredicate *predicate1 = [NSPredicate predicateWithFormat:@"SELF = %@",delegate.currentUser]; 

修改

似乎我错了:/这似乎只是起作用。