简体   繁体   English

执行与UITableViewController的核心数据联合等效的操作

[英]Performing the equivalent of a union with Core Data for a UITableViewController

I know union is a SQL construct, but it's the best analogue for what I'm trying to do. 我知道联合是一个SQL构造,但这是我要尝试的最佳模拟。

I have multiple groups of data that I'm receiving from an external source. 我有从外部来源接收的多组数据。 I'm maintaining them as separate entities in Core Data (they only have some attributes in common (eg name)), but I want to present them in the same tableView . 我在Core Data中将它们维护为单独的实体(它们只有一些共同的属性(例如,名称)),但是我想将它们呈现在同一tableView

Say I have an entity Food that has relationships with FruitGroup and VegetableGroup. 假设我有一个实体Food,它与FruitGroup和VegetableGroup有关系。 The FruitGroup has a relationship with Fruit which has a relationship with FruitType. FruitGroup与Fruit有关系,而Fruit与FruitType有关系。 The VegetableGroup is similar. VegetableGroup类似。

How can I use FruitGroup.Fruit.name and VegetableGroup.Vegetable.name as sectionTitles? 如何使用FruitGroup.Fruit.name VegetableGroup.Vegetable.name作为sectionTitles? And FruitGroup.Fruit.FruitType.name and VegetableGroup.Vegetable.VegetableType.name for row data. 行数据使用FruitGroup.Fruit.FruitType.name VegetableGroup.Vegetable.VegetableType.name。 (I tried coming up with a predicate that walks down from Food, but that doesn't appear to be workable) (我尝试提出一个从Food下来的谓词,但似乎不可行)

Example modeled data (my groups are far more disparate than fruits and veggies, so re-doing my data model is not an option): 示例数据模型(我的小组比水果和蔬菜要分散得多,因此无法重新创建数据模型):

Food
  FruitGroup
     Apple
         Macintosh
         Granny Smith
     Pear
         Bartlett
         Asian
         Anjou
  VegetableGroup
     Asparagus
         white
         wild
     Peas
         baby
         split

Which I would like to appear as: 我想显示为:

Apple [section]
   Macintosh   [row]
   Granny Smith
Pear
   Bartlett
   Asian
   Anjou
Asparagus
   white
   wild
Peas
   baby
   split

I could use multiple NSFetchedResultsControllers in the UITableViewController and conditionally select the FRC within each of the UITableViewDataSource methods, but that doesn't feel clean. 我可以在UITableViewController使用多个NSFetchedResultsControllers并在每个UITableViewDataSource方法中有条件地选择FRC,但这并不干净。

I'm thinking about subclassing NSFetchedResultsController and, internal to my subclass, merging the results of multiple private NSFetchedResultsControllers that each represent one of the entities. 我正在考虑对NSFetchedResultsController进行子类化,并在我的子类内部,合并每个代表一个实体的多个私有NSFetchedResultsControllers的结果。 (eg sections returns a concatenation of the returns from the sections calls of the internal FRCs) (例如,各部分返回内部FRC的各部分调用的收益的串联)

Does this make sense - or is there a better way? 这有意义吗?还是有更好的方法? (I saw Core Data Union Query Equivalent but since there are relationships among my entities, I wanted to seek alternatives) (我看到了等效的核心数据联合查询,但是由于我的实体之间存在关联,因此我想寻求替代方法)

While you can do this as described in the other answers (via creating an abstract Parent entity), I would not recommend it. 尽管您可以按照其他答案中的说明进行操作(通过创建抽象的Parent实体),但我不建议这样做。 The performance when it comes to dealing with abstract parents gets bad very quickly. 与抽象父母打交道时的表现会很快变差。 The reason for this is that Core Data will put all of the children into a single table in the underlying SQLite file. 这样做的原因是,Core Data会将所有子项放入基础SQLite文件中的单个表中。

I would suggest going a different route. 我建议走另一条路。 Have a single entity called Food with attributes describing if it is a vegetable or fruit. 有一个名为Food的实体,其属性描述了它是蔬菜还是水果。 Then you have one NSFetchedResultsController which has the type of the food item as the sectionPath and you will get your display the way that you want it. 然后你有一个NSFetchedResultsController它有type的食品作为sectionPath的,你会得到你的显示器,你想要的方式。

I recommend creating entities in Core Data based on what the objects are as a very loose level. 我建议根据对象的松散程度在Core Data中创建实体。 I would not create entities for Honda, Ford and Dodge, but create an entity for Car and perhaps type or a relationship to a manufacturer. 我不会为本田,福特和道奇创建实体,而是为Car以及可能与制造商的类型或关系创建实体。

While Core Data can be backed by a database, at the end of the day it is not a database but an object graph and should be treated as such. 虽然核心数据可以由数据库支持,但归根结底,它不是数据库,而是对象图,应这样处理。 Trying to normalize the database will result in poor performance of the object graph. 试图规范化数据库将导致对象图的性能下降。

To answer your question: 要回答您的问题:
You cannot unify different entity types (if they are not subclasses of the same entity) under a single fetch request. 您不能在单个提取请求下统一不同的实体类型(如果它们不是同一实体的子类)。 You can define an entity ( B ) to inherit from another entity ( A ) and then fetch by the parent entity ( A ) and get both kind of entities ( A s and B s) 您可以定义一个实体( B )从另一个实体( A )继承,然后由父实体( A )提取并获得两种实体( AB

You can try and think of it this way: 您可以尝试通过以下方式进行思考:

Item ("Macintosh","White Asparagus",...) has a relationship to Group ("Apple","Asparagus",...), and Group has a relationship to Area (or simply to another parent group). Item (“ Macintosh”,“白芦笋”,...)与Group (“ Apple”,“芦笋”,...)有关系,而Group与“ Area (或仅与另一个父组)有关系。

In this manner you could use a single FRC with sectionNameKeyPath of "group.name" and entity Item (you can filter by "group.area" to only select food items). 通过这种方式,您可以使用带有sectionNameKeyPath为“ group.name”和实体Item的单个FRC(您可以按“ group.area”进行过滤以仅选择食品)。

You should probably look into abstract entities. 您可能应该研究抽象实体。 For example, you could create an abstract entity called Food . 例如,您可以创建一个名为Food的抽象实体。 Then you're able to create Fruit and Vegetables , which inherits the abstract entity. 然后,您可以创建Fruit and Vegetables ,它继承了抽象实体。 You'll have to set Food as the "Parent Entity". 您必须将Food设置为“父实体”。

Then you could fetch all the items with the entity Food , which includes both Fruit and Vegetables . 然后,您可以使用实体Food (包括FruitVegetables来获取所有物品。 Based on your post, you'll probably will have a relation from Food to FoodGroup . 根据您的帖子,您可能会有一个从FoodFoodGroup的关系。

声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM