【问题标题】:Core data and sorting after a join condition连接条件后的核心数据和排序
【发布时间】:2011-07-14 11:01:45
【问题描述】:

我的核心数据表中有 3 个表。
项目表:项目,它有一个 ID 列和一个到属性表的连接。
属性表:它有一个 propertyValue 列和一个到项目表的连接和一个到属性表的连接。
属性表:它有一个 propertyName 列和一个到属性表的连接。

属性表包含一个名为“price”的属性名称。
属性表包含属性“price”的属性值“20”。
你认为我可以按价格对 Items 表进行排序吗?

我正在使用NSFetchedResultsController,我正在为它创建一个NSFetchRequest。 我试图为NSFetchRequest 编写一个带有比较器块对象的 NSSortDescriptor。它不工作。在此之后,我尝试编写一个没有任何选择器或块对象的 NSSortDescriptor,我只是设置了一个名为“dealPrice”的键,并使用名为 - (NSString *)dealPrice 的方法在 Item 托管对象上创建了一个类别。它也没有工作。

你知道其他方法吗?或者你知道解决办法吗?

【问题讨论】:

  • 在考虑 CoreData 时,您应该停止考虑数据库和表。 Getting Started With Core Data
  • 好吧,我知道我必须停下来了,我已经阅读了你链接的所有文件。所以让我们把“table”这个词改成“entity”这个词:)
  • 哪个实体 ItemProperty 对象将填充表格视图,即哪个实体是获取结果控制器的获取请求实体的集合?这是了解如何配置排序描述符的关键细节。

标签: ios sorting core-data


【解决方案1】:

您显然遇到了 SQL 热病的严重案例。您试图将 Core Data 视为 SQL 包装器,这将一切都搞砸了。

核心数据不是 SQL。实体不是表格。对象不是行。属性不是列。关系不是连接。 Core Data 是一个对象图管理系统,它可能会也可能不会持久化对象图,并且可能会或可能不会在幕后使用 SQL 来做到这一点。试图用 SQL 术语来思考 Core Data 会导致您完全误解 Core Data 并导致很多痛苦和浪费时间。

不应根据 UI 的需要或任何其他非数据要求来配置 Core Data 数据模型。相反,它应该准确地建模/模拟应用程序处理的真实世界对象、事件或条件。

在这种情况下,您正在建模:

  1. 一种具有名称和价格的属性。
  2. 由某种 id 表示的项目
  3. 一个或多个特定属性实例与一个或多个项目实例之间的关系。

因此,您的数据模型只需要通过关系连接的两个实体。您不需要“加入”,因为关系会自动处理两个实体之间的连接。

最简单的模型只有一对一的关系:

Item{
  id:string
  property<-->Property.item
}

Property{
  name:string
  price:number
  item<-->Item.property
}

如果每个Item 对象可以有多个关联的Property 对象,那么您将拥有:

Item{
  id:string
  properties<-->>Property.item
}

Property{
  name:string
  price:number
  item<<-->Item.properties
}

如果每个Property 对象可以有多个关联的Item 对象:

Item{
  id:string
  property<<-->Property.items
}

Property{
  name:string
  price:number
  items<-->>Item.properties
}

如何配置排序描述符取决于关系的详细信息以及表格视图将显示的实体对象。

【讨论】:

  • 好观点,在这个模型中,我想将 Property 实体中的 'price' 属性更改为 'value',然后,'name' 属性可以有 'price' 字符串并且“价值”属性可以有一个总和。在这种情况下,您希望如何按价格对商品进行排序?
  • 所以,在我看来,每个项目可以有多个属性,每个属性可以有多个项目。
  • 将关系更改为to-many-to-many 并没有真正改变太多,尽管它可以使谓词和排序等事情变得更加复杂。良好设计的关键是仔细研究应用程序旨在解决的实际逻辑问题,然后创建尽可能接近现实世界的实体和关系。
  • 我建议避免使用像 value 这样的名称,因为 Objective-C 全局开放名称空间。 API 中有很多东西叫做value,所以你可能会遇到命名冲突。为了安全起见,试试propValue 之类的东西。此外,现实世界的Property 对象是否实际上同时具有pricevalue 属性。大多数事情都没有。通常价格就是价值,反之亦然。除非绝对必须,否则请确保不要将属性添加为实现细节。
【解决方案2】:

我首先建议不要将 CoreData 视为数据库。它不是数据库。你称之为“表”的东西实际上是实体。将它们视为对象,具有与其他对象的属性和关系。考虑使您的数据模型尽可能简单。不要尝试针对数据库性能等优化您的结构。实际的支持架构不在您的控制之下。

考虑到这一点,从您发布的有关您的数据模型的内容来看,您似乎应该能够折叠成至少 2 个实体而不是 3 个(可能是 1 个,但在没有看到整个数据模型的情况下不确定)。然后,您应该能够使用根据相关对象的属性排序的谓词对 Items 实体进行简单的提取。

【讨论】:

  • 好的,我的问题是,我不能使用触发器。假设我有一个总是变化的属性,我怎么能强制 Core Data 在我获取它之前更新另一个属性?
  • 阅读 KVO,根据我对您上述评论的理解,这可能很有用,但我不完全理解您的意思。你能更详细地描述一下吗?
  • @infinity -- 托管对象上下文使用键值观察来管理托管对象。数据模型告知上下文所有内容如何组合在一起。当您在任何托管对象中进行更改时,上下文会观察更改,然后向已注册更改通知的任何对象发送通知,例如获取的结果控制器。你这样做太难了。 Core Data 会自动处理您尝试处理的所有事情。
  • @Paul - 我想我知道 KVO,我想 :) @TechZen - 谢谢,我开始理解这个概念了
【解决方案3】:

听起来您的真实对象模型是和名为 Dealentity 与名为“price”的attribute

【讨论】:

  • 是的,没错,但我认为,在这种情况下,这并不重要.. :)
猜你喜欢
  • 1970-01-01
  • 1970-01-01
  • 2014-08-20
  • 1970-01-01
  • 1970-01-01
  • 2011-04-17
  • 1970-01-01
  • 1970-01-01
  • 2011-01-22
相关资源
最近更新 更多