【问题标题】:CoreData - select specific entry from one to many relationshipCoreData - 从一对多关系中选择特定条目
【发布时间】:2010-12-01 09:42:49
【问题描述】:

该死的短标题! :p

基本上我有一个名为“threads”的实体,我有一个名为“messages”的实体。我有来自线程的一对多关系 ->> 消息(以及一对一的反向关系)。

我需要做的是从线程实体中获取所有记录,并且对于每个记录,我需要获取具有最新时间戳的消息(这只是“lastUpdated”属性中的一个 int,所以我猜是最高数字就够了)。

我不确定您可能还需要什么其他信息,这是我的实体的屏幕截图:

我确定一定有比遍历所有记录并比较 threadId 更好的方法吗?

谢谢。

【问题讨论】:

  • 我一直想在我自己的应用中做这样的事情,但不知何故总是忘记在这里发帖询问。
  • 是的,通常我只是比较线程 ID,但这个项目主要基于核心数据,所以我想我会努力学习如何使其高效并学习有关关系的所有内容等等。但是,在任何地方都找不到有关核心数据的太多信息。 :(

标签: iphone objective-c core-data


【解决方案1】:

一旦你有了单独的 Thread 对象,你只需要对 Messages 对象进行排序并获取最顶层的 Message 对象。

最简单的解决方案是在 Thread 类中创建一个方法,如下所示:

- (Messages *) lastUpdatedMessage{
    NSSortDescriptor *sort=[NSSortDescriptor sortDescriptorWithKey:@"lastUpdated" ascending:NO];
    NSArray *sortedMessages=[self.messagesInThread sortedArrayUsingDescriptors:[NSArray arrayWithObject:sort]];
    return [sortedMessages objectAtIndex:0];
}

那么您所要做的就是向每个 Thread 对象询问其 lastUpdatedMessage。

更复杂但更有效的解决方案是创建一个中间链接实体,它将一个 Message 对象链接到一个 Thread 对象,并将该链接对象设置为 Message 对象更新。所以:

MessageThreadLink{
    message<--(required)-->Message.lastUpdateLink
    thread<--(required)-->Thread.lastUpdatedMessage
}

每当一个 Message 对象更新时,它会告诉它的相关 Thread 对象删除现有的链接对象并创建另一个指向它的对象。您可能会将该代码放在 lastUpdated 属性的自定义设置器中。

使用此方法,您只需要向每个线程询问其 lastUpdatedMessage,它就会自动出现,无需进行大量搜索和排序。

【讨论】:

  • 最好的(任何?)方法来做到这一点,而不会将所有消息拉入内存并对其进行排序?最好在数据库中进行排序,然后为查询设置一个限制 1,这样你就只能得到你想要的那个。 (想象一下 1M 条消息)。我猜你必须改变模型?
【解决方案2】:

您不能像在简单数据库上执行查询一样,只使用NSPredicate 对您需要的数据和属性值执行过滤吗? (或者也许我错过了一点)

【讨论】:

  • 我可以做到,但是关系有什么意义呢?!我原以为会有一种方法可以通过关系访问实体。
  • 我猜你误解了关系或者我误解了你:) 关系只是数据库概念模型(如 ER/EER)中关系 的面向对象的抽象因此您可以通过集合(NSSet)和关键路径评估访问参与关系的项目。因此,最有效的方法是让 Core Data 通过在给定当前数据模型的情况下使用 Predicate 来获取您需要的内容。也许您可以按照 Rog 的建议更改数据模型以获得更高的性能
【解决方案3】:

所以你的 lastUpdated 属性是一个 int 而不是 NSDate?如果是这样,它是否必须是一个 int 并且您是否对存储在该属性中的数据执行其他任何操作?

我在想您可以使用 BOOL 属性将消息标记为 lastUpdated == YES,然后您需要做的就是获取与该谓词匹配的消息实体。您仍然可以通过一对一关系访问线程实体,以便以您想要的方式获取和显示该数据。

[编辑] 作为旁注,我认为您可能会发现使用单数词来命名您的实体更直观,因为每个 Thread 实体包含一个线程,每个消息实体包含一个消息。

或选项 2

将您的 lastUpdated 属性更改为 NSDate 并为 NOW 设置默认值,以便在创建实体时将使用当前日期/时间预先填充。

然后对于您保存的每个线程,拉取关联的消息,按 NSDate 对它们进行排序,如果 ASCENDING == NO 则选择数组中的第一个对象,如果 ASCENDING == YES 则选择最后一个对象。

【讨论】:

  • 对,所以您是说(第二种选择)是唯一的方法?没有办法使用关系来做到这一点?
  • 可能有其他方法,但无论您做什么,您都必须获取符合特定条件的所有消息 - 一旦完成,您就可以访问它们的关系以获取关联的线程。绝对比最初建议的拉取和比较所有 threadId 更有效。
猜你喜欢
  • 1970-01-01
  • 2013-11-13
  • 2014-07-19
  • 1970-01-01
  • 1970-01-01
  • 2020-12-15
  • 1970-01-01
  • 1970-01-01
  • 2017-01-24
相关资源
最近更新 更多