【问题标题】:Grouping a Core Data data result?对 Core Data 数据结果进行分组?
【发布时间】:2011-01-21 23:02:38
【问题描述】:

我正在 iPhone 上制作一个想法的原型,但我正处于 SQLite 与 CoreData 的十字路口。主要原因是我似乎无法弄清楚如何对核心数据进行分组。

基本上我想显示按用户名分组的最近发布的项目。在 SQL 语句中很容易做到,但我无法让它在核心数据中工作。我想既然我正在启动一个新应用程序,我不妨尝试让核心数据工作,但这部分是一个主要障碍。

我在我的 fetchrequest 中添加了一个谓词,但这只给了我最近添加的一条记录,而不是每个用户最近添加的记录。

此时的数据模型非常基础。它使用以下字段: 用户名(字符串),帖子(字符串),创建(日期时间)

长话短说,CoreData 可以进行这些类型的查询吗?我想,如果 SQLite 在幕后,一定有办法做到这一点。

【问题讨论】:

    标签: objective-c cocoa sqlite core-data


    【解决方案1】:

    如果 'posts' 是一个用户的 NSSet,你可以得到最后一个带有谓词的帖子:

    NSDate *lastDate = [userInstance valueForKeyPath:@"@max.date"];
    
    NSSet *resultsTemp = [setOfPosts filteredSetUsingPredicate:[NSPredicate predicateWithFormat:@"fecha==%@", lastDate] ];
    

    resultsTemp 集将包含一个 Post 类型的对象,该对象具有最新的日期。

    【讨论】:

      【解决方案2】:

      首先,不要将 Core Data 视为执行 SQL 的另一种方式。 SQL 不是核心数据的“底层”。 Core Data 处理对象。实体描述不是表,实体实例不是记录。使用 Core Data 进行编程与 SQL 无关,它只是将 SQL 用作几种可能的持久存储类型之一。您不直接处理它,也不应该用 SQL 术语来考虑 Core Data。

      那是疯狂。

      你需要喝大量的龙舌兰酒,反复打自己的脑袋,直到你忘记你曾经知道的关于 SQL 的一切。否则,您最终将得到一个只是一个大电子表格的对象图。

      有几种方法可以在 Core Data 中完成您想要的。通常,您会使用复合谓词构造 fetch,该谓词将返回特定用户在特定日期范围内发布的所有帖子。获取结果控制器对此特别方便。

      最直接的方法是设置对象图,如下所示:

      UserEntity
      --Attribute username
      --Relationship post <-->> PostEntity
      
      PostEntity
      --Attribute creationDate
      --Attribute content
      -- Relationship user <<--> UserEntity
      

      然后在你的 UserEntity 类中有一个这样的方法:

      - (NSArray *) mostRecentPost{
          NSPredicate *recentPred=[NSPredicate predicateWithFormat:@"creationDate>%@", [NSDate dateWithTimeIntervalSinceNow:-(60*60*24)]];
          NSSet *recentSet=[self.post filteredSetUsingPredicate:recentPred];
          NSSortDescriptor *dateSort=[[NSSortDescriptor alloc] initWithKey:@"creationDate" ascending:NO];
          NSArray *returnArray=[[recentSet allObjects] sortedArrayUsingDescriptors:[NSArray arrayWithObject:dateSort]];
          return returnArray;
      }
      

      当您想要按日期排序的特定用户的最新帖子列表时,只需调用:

      NSArray *arrayForDisplay=[aUserEntityClassInstance mostRecentPost];
      

      编辑:

      ...我只是通过每个帖子块 数据(内容,创建日期)到 发布实体?我是否也通过了 帖子实体的用户名?如何 用户实体知道何时创建 新用户?

      让我对其进行伪编码。您有两个类定义了 userObj 和一个 postObj 的实例。当有新帖子出现时,您:

      Parse inputPost for a user;
      Search existing userObj for that name;
      if userObj with name does not exist
          create new userObj;
          set userObj.userName to name;
      else 
          return the existing userObj that matches the name;
      Parse inputPost for creation date and content;
      Search post of chosen userObj;
      if an exiting post does not match content or creation date
          create new postObj
          set postObj.creationDate to creation date;
          set postObj,content to content;
          set postObj.user to userObj; // the reciprocal in userObj is created automatically
      else // most likely ignore as duplicate
      

      您有单独的 userObj 和 postObj,因为虽然每个帖子都是唯一的,但每个用户可能有很多帖子。

      要掌握的重要概念是您处理对象,即数据和逻辑的封装实例。这不仅仅是数据库中的行和列。例如,您可以编写托管对象子类,其中单个实例可以决定是否与另一个类的实例形成关系,除非达到对象的特定内部状态。 dbs 中的记录没有那种逻辑或自主性。

      掌握将对象图用于数据模型的最佳方法是不仅忽略 db,而且忽略 Core Data 本身。相反,着手编写一个小型测试应用程序,您可以在其中手动编写所有数据模型类的代码。不必详细说明每个类的几个属性和对另一个类的某种引用。想想您将如何管理将数据解析到每个类,将类及其数据链接在一起,然后将其取回。手动执行一次或两次,对象图的性质就变得很明显了。

      【讨论】:

      • 感谢您的详尽解释和 +1 “您需要喝很多龙舌兰酒并反复敲打自己的脑袋,直到您忘记您对 SQL 的所有了解。”只是为了确保我从非 SQL 角度理解这一点,当我解析包含列出其用户的帖子的新数据(xml、json 等)时,我是否只传递每个帖子数据块(内容、创建日期)到邮政实体?我是否也将用户名传递给 post 实体?用户实体如何知道何时创建新用户?是吗?
      • 伪代码做到了。我想确保我负责创建逻辑以查看用户是否存在或是否自动发生。再次感谢。
      • 上面示例代码中的UserEntity类方法应该是类方法(带+)还是您显示的实例方法?
      • 它必须是一个实例方法,因为它依赖于self.post,它引用了UserEntity实例的post属性。
      【解决方案3】:

      还有其他考虑因素可能会促使您决定使用 SQLite 还是使用 SQLite 存储的 Core Data。我发现自己在阅读好的blog post on the subject 时点头表示同意。我发现了完全相同的事情(因此我将高性能应用程序从 Core Data 中移出):“Core Data 是正确的答案,除非它不是......”

      这是一项很棒的技术,但一个尺寸绝对不能满足所有人的需求。

      【讨论】:

      • 核心数据经过优化以处理复杂性,而 SQL 经过优化以处理大小。如果您有大量简单的、基本上不相关的记录,那么原始 SQL 将提供卓越的性能。如果您拥有相对少量(绝对)具有许多互连逻辑关系的许多不同逻辑实体,那么 Core Data 显然更胜一筹。
      • 我也读过那篇文章,这就是为什么我非常不愿意放弃我使用 SQL 的经验。我想我现在唯一能做的就是模拟两个版本,看看哪个更像是我把自己画到一个角落里。
      • 一般来说,TechZen,这是一个非常合理的。 :-)
      猜你喜欢
      • 2013-05-04
      • 2012-10-06
      • 1970-01-01
      • 2023-02-08
      • 1970-01-01
      • 2021-03-26
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      相关资源
      最近更新 更多