CoreData 对多对多关系进行排序
我正在编写一个 iOS 应用程序,其中存储了人员记录,并且需要显示以特定方式排序的列表。这些订单的数量是可变的,并且它们是动态生成的,但我希望它们存储在数据存储中。执行此操作的 SQL 方法是创建一个 ListPositions 表,其中包含列表名称、persons 表中的 id 和排序键。然后,为了显示特定列表,我可以选择具有给定名称的所有列表 ListPosition,拉入引用的人员,然后按排序键进行排序。尝试在 CoreDatat 中执行此操作,但遇到了问题。我尝试使用如下模式来执行此操作:
Person:
Name
DOB
etc...
positions -->> ListPosition
ListPosition:
listName
sortKey
person --> Person
然后,我可以使用 NSPredicate 获取给定列表中的所有人员 [NSPredicate predicateWithFormat:@"ANY Positions.listName like %@", someList];
这允许我动态添加针对大量人员的列表。问题是我无法使用 ListPosition 的 sortKey 字段对人员进行排序。什么 NSSortDescriptor 会执行此操作?如果无法对一对多关系的一个元素的属性的获取进行排序,那么在 coredata 中获取多个动态排序的另一种方法是什么?我使用 NSFetchedResultsController 显示列表,因此我无法自己将列表放在内存中。我需要用一个 NSFetchRequest 来完成它。
I'm writing an iOS app which has store of person records, and needs to display lists them sorted in particular ways. There are a variable number of these orderings, and they are generated on the fly, but I would like them to be stored in the datastore. The SQL way to do this is to have a ListPositions table with a list name, an id into the persons table, and a sort key. Then, to display a particular list, I can select all list ListPositions with a given name, pull in the referenced persons, and sort on the sort key. Trying to do this in CoreDatat, however I run into problems. I am trying to do this using a schema like:
Person:
Name
DOB
etc...
positions -->> ListPosition
ListPosition:
listName
sortKey
person --> Person
Then, I can get all the Persons in a given list with the NSPredicate[NSPredicate predicateWithFormat:@"ANY positions.listName like %@", someList];
This allows me to dynamically add lists against a large set of Persons. The problem is that I am unable to use the sortKey field of ListPosition to sort the Persons. What NSSortDescriptor will do this? And if it is not possible to sort a fetch on the property of one element of a to-many relationship, what is another way to get multiple, dynamic orderings in coredata? I am displaying the lists with a NSFetchedResultsController, so I can't put the lists together myself in memory. I need to do it with a single NSFetchRequest.
如果你对这篇内容有疑问,欢迎到本站社区发帖提问 参与讨论,获取更多帮助,或者扫码二维码加入 Web 技术交流群。
绑定邮箱获取回复消息
由于您还没有绑定你的真实邮箱,如果其他用户或者作者回复了您的评论,将不能在第一时间通知您!
发布评论
评论(5)
你是对的——遵循一对多关系会返回一个 NSSet,它没有固有的排序。要获得排序结果,有几个选项:
[NSPredicate predicateWithFormat:@"person=%@", myPerson]
。在获取请求中使用您需要的任何排序描述符。-sortedArrayUsingDescriptors:
方法将其转换为排序数组。You're right-- following a to-many relationship returns an NSSet, which has no inherent sorting. To get sorted results there are a couple of options:
[NSPredicate predicateWithFormat:@"person=%@", myPerson]
. Use whatever sort descriptor you need on the fetch request.-sortedArrayUsingDescriptors:
method to convert that to a sorted array.我认为在这种情况下最好的方法是获取 ListPosition 实体。添加 sortKey 的排序描述符(在这种情况下它会起作用,因为获取请求位于 ListPosition 实体上),并在获取请求上使用 setRelationshipKeyPathsForPrefetching for “person” 预获取与列表名称关联的 Person。
I think the best approach in this case would be to fetch on ListPosition entity instead. Add the sort Descriptor for sortKey (it would work in this case because the fetch request is on ListPosition entity) and prefetch the Person associated with the the list name using setRelationshipKeyPathsForPrefetching for "person" on the fetch request.
如果我正确理解您的模型,则每个
Person
对于其参与的每个列表都有一个ListPosition
。假设我们有按姓名升序排列的列表,因此 X 个人有 X 个具有相同listName
和sortKey
的列表位置。我将创建实体
List
,其中包含sortKey
属性,然后在排序描述符中使用它。创建排序描述符并在获取请求中使用它:
然后您可以拥有任意数量的列表,并且您可以轻松地使用其排序键对所有人员进行排序。
如果您想将位置存储在数据库中(您没有在
ListPosition
中提到属性index
或类似的内容),您可以创建“联合实体”:另一个想法直接在
List
实体中订购了一组Person
对象。If I understand your model correctly, each
Person
has oneListPosition
for each list in which it participates. Let's say we have acsending list by their names, so X people have X list positions with the samelistName
andsortKey
.I would create entity
List
, that would contain thesortKey
attribute and then use it in sort descriptor.Create sort descriptor and use it in fetch request:
Then you may have as many Lists as you want and you can easily use its sort key to sort all people.
If you want to store the positions in database (you didn't mention attribute
index
in yourListPosition
, or anything similar), you can create “joint entity”:Another idea is having ordered set of
Person
objects directly inList
entity.获取 ListPosition(它将作为 NSMutableSet 出现)。然后对 Set 进行排序,如下所示:
这将根据您的键为您提供一个排序后的数组。
Get the ListPosition (it will come as a NSMutableSet). Then do a sort on the Set, like this:
That will give you a sorted out array according to your key.
我通常向实体添加索引字段(类型 NSNumber)。添加项目时计算索引非常容易。这样
,实际上您不需要职位字段,而是职位关系。将 person 实体连接到 ListPosition 实体就足够了。
I usually add an index field (type NSNumber) to an entity. It's very easy to calculate index in adding item. just by
so, actually you don't need positions field but positions relationship. connect person entity to ListPosition entity would be enough.