核心数据:可能进行大量更新?

时间:2010-03-16 18:34:52

标签: iphone cocoa-touch core-data

是否可以在Core Data中对给定实体进行批量更新?

例如,给定一个Person实体,我可以这样做:

Person.update(@"set displayOrder = displayOrder + 1 where displayOrder > 5")

或者我唯一的选择是获取所需的所有实体,然后循环并单独更新它们

由于

5 个答案:

答案 0 :(得分:4)

您正在考虑将Core Data作为SQL。大错。

实体不是表格,实例不是记录。每个实例都是它自己的对象,因此您必须单独更改它们。否则,使用对象图没有多大意义。

Edit01:

  

那怎么会   您处理以下UI问题:   您想要呈现一个人员表   按“名称”排序的实体。但......   用户可以重新订购Person   此表中显示的实体和您   希望坚持这样的   实体现在按“名称”+排序   “displayOrder”(或任何你想要的   称之为)。你在哪里维护   “displayOrder”的值,如果不是   Person实体的属性?

哦,我明白你要做什么了。你使它变得比它必须要困难得多。 Core Data可以轻松处理这类功能。

排序顺序不是(通常,见下面)数据模型的方面,而是视图控制器,即它们只是用于以有意义的方式向用户显示数据的临时命令。因此,它们是根据需要即时创建的。在这种情况下,您将创建一个NSSortDescriptor / s来对您希望的属性键进行排序。然后设置您的获取请求以使用这些排序描述符。然后你的fetch将返回一个包含所需顺序元素的数组。

没有大惊小怪。

如果用户想要一个不同的排序顺序,只需创建一组不同的排序描述符。没有理由在实际数据模型本身中包含排序逻辑,并且有许多原因不能做。

在所有iPhone API基于的模型 - 视图 - 控制器设计模式中,将实际数据与显示分离非常重要。您不希望在数据模型中包含显示逻辑,并且您不希望存储数据或在显示中使用数据操作逻辑。

Edit02:

  

在我的情况下,用户需要能够   回到应用程序,查看   该表并查看Person实体   按照他们给他们的顺序。能怎样   你可以这样做,除非有一个   displayOrder属性?

如果您确实希望将订单保存为用户数据,则需要将其包含在数据模型中。

巧合的是,我只是有这样的需要。 Here's how I handled the problem for a small number of objects.这些是NSMangedObject子类的方法。这适用于数百个轻量级对象。

如果您有大量重量级对象(数千个),我建议创建一个轻量级实体来实现链接列表。称之为OrderEntity。它将具有索引属性,与索引实体的关系,与先前OrderEntity的关系以及与下一个的关系。 (使用轻量级实体可以防止您丢失重型对象,从而节省内存并使一切变得更快。您只需在需要显示索引对象时对其进行故障。)

然后使用标准链表方法插入,交换和移动列表中的项目。然后,您调用已移动对象的更新,并调用所有后续OrderEntities来更新其索引。

它可以像调用下一个OrderEntity的方法一样简单,传递当前对象索引并告诉下一个将其顺序设置为passIndex + 1。这基本上是您想要模仿的SQL语句的确切函数(因为逻辑当然是相同的。)

如果必须执行此操作,请创建一个NSManagedObject子类来处理索引,然后让索引类继承该索引。

答案 1 :(得分:1)

不,您无法在Core Data中执行“批量”更新。如果您认为自己想要这样做,那么您从根本上就忽略了核心数据:它不是不是关系数据引擎,它是一个图形管理框架引擎。您描述的批量更新是您对数据表的处理方式。迭代对象图是您使用的对象图管理引擎。

当您的数据真的是表格式(如您的那样)时,核心数据可能不是最佳选择。批量更新问题是Brent Simmons对某些应用程序来自Core Data switched away的原因之一。与往常一样,使用正确的工具来完成正确的工作。

在这种情况下,可能有更好的方法来做你想要的。显示顺序实际上不是模型属性;它更适合于视图属性。您可能想要创建一个fetched属性,在模型中对某些内容进行排序。如果是日期,请拥有日期属性。如果它是显示顺序首选项,您可能希望将项目保留在链表样式图中,其中每个实例都具有上一个/下一个关系。更新这个很容易,并且显示它们(顺序操作)也很容易。

答案 2 :(得分:1)

这样做的正确方法是获取所有Person对象的数组(只需为所有Person实体创建一个获取请求而不指定谓词)。

然后使用NSArray方法makeObjectsPerformSelector:withObject:来应用批量更改 - 您可能需要在对象上创建自定义方法,以使其执行所需的确切更改。

然后在NSManageObjectContext上调用save,您的更改将被存储。

正如其他人所说,它不像SQL那样发布文本更新 - 但这并不意味着你不能再进行批量更改。

答案 3 :(得分:1)

使用Core Data无法进行批量类SQL更新,您必须遍历所有对象才能更新值。

如果需要保存displayOrder属性,则需要将其作为属性存储在数据模型中。这是一个常见的问题,我很惊讶它还没有内置的解决方案。

答案 4 :(得分:0)

你不能这样做,至少不能绕过整个Core Data对象层次结构(实际上真的不推荐)。