核心数据:如何计算具有特定属性值的一对多关系中的实体?

时间:2012-01-17 12:07:18

标签: objective-c cocoa core-data

以下是我的数据模型示例:

  • 有邮箱
  • 每个邮箱都有很多邮件
  • 每条消息都有一个标志,指示它是否未读

如何计算特定邮箱的未读邮件数

我尝试在数据模型编辑器中创建获取请求,但我无法为邮箱添加条件,尽管邮件实体已为其拥有的邮箱定义了关系。

我知道在处理核心数据时我不应该在SQL中思考,但感觉很自然,所以说:

SELECT count(*) FROM Messages WHERE unread = 1 AND mailboxId = 12345

除了循环播放特定邮箱的每封邮件之外,还有其他方法可以获取未读邮件吗?

3 个答案:

答案 0 :(得分:5)

您想要在不提取对象的情况下进行计数,因为这需要更长的时间:

- (NSUInteger)countForFetchRequest:(NSFetchRequest *)request error:(NSError **)error

返回给定获取请求传递给executeFetchRequest时返回的对象数:错误:

您还需要在获取请求中添加一个谓词(即WHERE子句)。

e.g

NSFetchRequest * request = [[NSFetchRequest alloc] init];
[request setEntity: [NSEntityDescription entityForName:@"Messages" inManagedObjectContext:context]];
[request setPredicate:[NSPredicate predicateWithFormat: @"(unread == 1 && mailboxId == %i)", mailboxId]];

(我的谓词语法错误......但你应该明白这个想法)

答案 1 :(得分:0)

下面的代码会计入未读Messages,其中包含unread == YES和(假设mailbox}关系),邮箱的id == 12345

NSFetchRequest * request = [[[NSFetchRequest alloc] init] autorelease];
request.entity = [NSEntityDescription entityForName: @"Messages" inManagedObjectContext: context];

request.predicate = [NSPredicate predicateWithFormat: @"(%K == %@) && (%K == %@)",
                                    @"unread", [NSNUmber numberWithBool: YES], 
                                    @"mailbox.id", @"12345"];

NSError * error = nil;
int count = [[self managedObjectContext] countForFetchRequest: request error: &error];

(注意:我喜欢使用%K作为密钥路径的占位符,因为我为属性名称声明了常量字符串。)

答案 2 :(得分:-1)

以下代码执行所需任务:

NSEntityDescription *entity = [NSEntityDescription entityForName:@"MessageEntity" 
                                                      inManagedObjectContext:appDelegate.managedObjectContext];

NSPredicate *predicate = [NSPredicate predicateWithFormat:@"(unread == %i)", 1];
NSFetchRequest *fetchRequest = [[[NSFetchRequest alloc] init] autorelease];
[fetchRequest setPredicate:predicate];
[fetchRequest setEntity:entity];

NSArray *allResults = [appDelegate.managedObjectContext executeFetchRequest:fetchRequest error:nil];

NSMutableArray *filteredSet = [[NSMutableArray alloc] init];
for(yourMailboxEntityObject *aMailBox in allResults) {
    if(aMailbox.mailboxId == your_desired_id)
        [filteredSet addObject:aMailBox];
}

//do your code
NSLog(@"unreaded messages: %d", [filteredSet count]);

//be sure to release the filteredSet...
[filteredSet release];