I know union is a SQL
construct, but it's the best analogue for what I'm trying to do.
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
.
Say I have an entity Food that has relationships with FruitGroup and VegetableGroup. The FruitGroup has a relationship with Fruit which has a relationship with FruitType. The VegetableGroup is similar.
How can I use FruitGroup.Fruit.name and VegetableGroup.Vegetable.name as sectionTitles? And FruitGroup.Fruit.FruitType.name and VegetableGroup.Vegetable.VegetableType.name for row data. (I tried coming up with a predicate that walks down from Food, but that doesn't appear to be workable)
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.
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. (eg sections returns a concatenation of the returns from the sections calls of the internal FRCs)
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. 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.
I would suggest going a different route. Have a single entity called Food with attributes describing if it is a vegetable or fruit. 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.
I recommend creating entities in Core Data based on what the objects are as a very loose level. 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.
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)
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).
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).
You should probably look into abstract entities. For example, you could create an abstract entity called Food
. Then you're able to create Fruit
and Vegetables
, which inherits the abstract entity. You'll have to set Food
as the "Parent Entity".
Then you could fetch all the items with the entity Food
, which includes both Fruit
and Vegetables
. Based on your post, you'll probably will have a relation from Food
to FoodGroup
.
The technical post webpages of this site follow the CC BY-SA 4.0 protocol. If you need to reprint, please indicate the site URL or the original address.Any question please contact:yoyou2525@163.com.