CoreData对多对多关系进行排序

时间:2011-02-06 20:29:36

标签: iphone cocoa-touch ios core-data nssortdescriptor

我正在编写一个iOS应用程序,它具有人员记录存储,并且需要显示按特定方式排序的列表。这些排序有可变数量,它们是动态生成的,但我希望它们存储在数据存储区中。执行此操作的SQL方法是使ListPositions表具有列表名称,人员表中的id和排序键。然后,为了显示特定列表,我可以选择具有给定名称的所有列表ListPosition,拉入引用的人员,并对排序键进行排序。试图在CoreDatat中执行此操作,但是我遇到了问题。我试图使用如下的模式来做到这一点:

Person:
    Name
    DOB
    etc... 
    positions -->> ListPosition

ListPosition:
    listName
    sortKey
    person --> Person

然后,我可以使用NSPredicate获取给定列表中的所有人员 [NSPredicate predicateWithFormat:@"ANY positions.listName like %@", someList]; 这允许我针对大量人员动态添加列表。问题是我无法使用ListPosition的sortKey字段对Persons进行排序。 NSSortDescriptor会做什么?如果无法对多对多关系的一个元素的属性进行获取,那么在coredata中获取多个动态排序的另一种方法是什么?我正在使用NSFetchedResultsController显示列表,因此我无法将这些列表放在内存中。我需要使用一个NSFetchRequest来完成它。

5 个答案:

答案 0 :(得分:3)

你是对的 - 在多对多关系之后返回一个NSSet,它没有固有的排序。要获得排序结果,有几个选项:

  1. 假设Person / ListPosition是双向关系,请对ListPosition实体执行新的获取请求。使用ListPosition对“person”关系进行谓词匹配,这看起来像[NSPredicate predicateWithFormat:@"person=%@", myPerson]。在获取请求中使用您需要的任何排序描述符。
  2. 按照你正在做的关系,给你一个NSSet。然后使用NSSet的-sortedArrayUsingDescriptors:方法将其转换为已排序的数组。

答案 1 :(得分:1)

我认为在这种情况下最好的方法是获取ListPosition实体。为sortKey添加排序描述符(在这种情况下它将起作用,因为获取请求在ListPosition实体上)并使用取指令上的“person”的setRelationshipKeyPathsForPrefetching预取与列表名称关联的Person。

[NSPredicate predicateWithFormat:@"listName like %@", someList];

答案 2 :(得分:1)

如果我正确理解您的模型,则每个Person对于其参与的每个列表都有一个ListPosition。假设我们的名字有一个按顺序列表,所以X人有X列表位置相同 listNamesortKey

我会创建实体List,它将包含sortKey属性,然后在排序描述符中使用它。

entity List:
    - sortKey : string
    - ascending : bool

创建排序描述符并在获取请求中使用它:

[NSSortDescriptor sortDescriptorWithKey:chosenList.sortKey ascending:chosenList.ascending];

然后您可以拥有任意数量的列表,并且可以轻松使用其排序键对所有人进行排序。


如果您想在数据库中存储职位(您未在index或类似内容中提及属性ListPosition),您可以创建“联合实体”:

entity PersonInList:
    - index : integer
    - person -> Person
    - list –> List

另一个想法是直接在Person实体中订购一组List个对象。

答案 3 :(得分:1)

获取ListPosition(它将作为NSMutableSet)。然后对Set进行排序,如下所示:

NSMutableSet *positionsSet = [personEntity mutableSetValueForKey:@"positions"];
NSSortDescriptor *sortDescriptor = [NSSortDescriptor sortDescriptorWithKey:@"yourSortKey" ascending:NO];
NSArray *positionsSortedSet = [positionsSet sortedArrayUsingDescriptors:[NSArray arrayWithObject:sortDescriptor]];

这将根据您的密钥为您提供一个整理的数组。

答案 4 :(得分:0)

我通常会向实体添加索引字段(类型NSNumber)。在添加项目时计算索引非常容易。只是通过

object.index = person.positions.count

所以,实际上你不需要职位领域而是职位关系。将person实体连接到ListPosition实体就足够了。