【问题标题】:Core Data: How to count entities in a one-to-many relationship with a specific attribute value?核心数据:如何计算具有特定属性值的一对多关系中的实体?
【发布时间】:2012-01-17 12:07:17
【问题描述】:

这是我的数据模型的示例:

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

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

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

我知道在处理 Core Data 时我不应该用 SQL 来思考,但感觉很自然,所以说:

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

除了遍历特定邮箱的每条消息之外,还有其他方法可以获取未读消息计数吗?

【问题讨论】:

    标签: objective-c cocoa core-data


    【解决方案1】:

    您想在不获取对象的情况下进行计数,因为这会花费更长的时间:

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

    如果给定的获取请求已被传递给 executeFetchRequest:error:,则返回该请求将返回的对象数:

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

    例如

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

    (我的谓词语法可能有误......但你应该明白)

    【讨论】:

    • 感谢您的超快速响应。按照您的建议使用谓词。这是我无法在获取请求中设置关系条件的事实,而只是数据模型编辑器的限制?
    • 您可以使用关键路径在谓词中设置关系条件,因此mailbox.id 将起作用(正如@Ashley Mills 的回答所建议的那样)。
    【解决方案2】:

    下面的代码将计算未读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 作为键路径的占位符,因为我为属性名称声明了常量字符串。)

    【讨论】:

      【解决方案3】:

      下面的代码执行所需的任务:

      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];
      

      【讨论】:

      • 错误答案。 @Mark 想要消息数。您的答案需要返回对象,然后进一步过滤集合,然后计算它们。只需让数据库完成工作并使用 countForFetchRequest:
      猜你喜欢
      • 1970-01-01
      • 2023-04-06
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      • 2013-03-19
      • 1970-01-01
      相关资源
      最近更新 更多