Search by properties of two Entities (fetch from two Entities) - ios

Let's say I have two entities, A and B. My goal is to implement the search by all properties of A and just one property of B, and to display sum of search results in one tableView. Naturally I can set fetchRequest only by one entity. But if I am understand right I can fetch not only from A but from B too if they are connected with relationships.
So what do I need to do to implement this? Does default fetch fetches all properties from A and B? If not, how can I specify fetch of all properties from A and one property of B in one fetch?

Issue solved.
At the stage of preloading data from JSON file into Core Data I am define getters for properties (prefetching data from entity)in B and setting entity properties of A equal to returned results of this getters (all this in NSManagedObject subclasses inherited from entities). So after that I am able to fetch all what I need using this getters through appropriate properties.

Related

Reason for setting relationships among entities in Core Data

After learning about relationships between entities in Core Data. I don't see the real reason for setting up relationship between two entities. They can be connected separately if one of the entities contains a property that can hold another entity by having a property of type NSManagedObject.
#property (nonatomic, strong ) NSManagedObject *AssetType;
This is a concept you must understand: Core Data is not a database but it is an object graph manager and, as a second functionality, offers persistence (e.g using for example a Sqlite store).
Said this, if you have two separated entities and you need to retrieve values based on the conditions that belong to the other entity, you need to run two requests and filter the results in memory. On the contrary if you set up a relationship you can just create a request wih a specific predicate and let Core Data to retrieve the correct results for you. In addition, through relationships you can access objects that belong to another entity as simple as accessing a property object. For example, the following snippet says that based on entityA I can access a property calles someRelationship that allows to retrieve one (or more) entities of type EntityB. If someRelationship has been set up as to-many you'll receive one or more EntityB entities.
entityB = entityA.someRelationship;
The real advice is to think in terms of objects graph!!!
Further reference: Core Data Overview by objc.io.
Update 1
The other big advantage is that relationships allow you to take advantage of deletion rules and, through inverse relationships, you are able to maintain the integrity of your graph.
See Relationships and Fetched Properties.

nsfetchedresultscontroller with 1-* and *-*

Maybe this is pushing NSFetchedResultsController too far... anyway, this is what I'm trying to do:
I have the core data classes and relationships: A <->> B <<->> C (A has 1 to many to B, B has many-to-many to C). I'm given one object of type A. I want to use NSFetchedResultsController to give me all reached objects of type C (NOT distinctly - I want duplicates), where the sectionNameKeyPath is the 'name' property of the B object. Possible? How?
I do not think that is possible with a NSFetchedResultsController. A FRC can
only display the result of a fetch request, and a fetch request returns
objects of a given entity without duplicates.

Core Data:Fetch rlelationships or Fetch Main Entity

I have an Entity A which has to-many relationships with Entity B.
Entity A -->> Entity B
I need to refer to the count of to-many relationship, at more than one screen. Further, I can remove and add reference to any Entity B from Entity A multiple times.
Now, the question is : What is the best way to refer the relationship count?
What I observed:?
1] I can make a count attribute in Entity A and increment/decrement it according to the relationship count and then fetch this attribute on screens I need.
2] I can also get the count from count property of NSSet(of relationships), this way I do not have to fetch the EntityA. I can simply do,
NSSet *set = EntityA.EntitiesB;
NSInteger count = set.count;
This way also fetch happens but I do not have to create a fetch request again and again for EntityA.
Appreciate any help.
You don't actually have to fetch anything, you can create your fetch request with suitable predicate and then use countForFetchRequest:error: to get the count. You could also create a fetch request template (setFetchRequestTemplate:forName:) and then use fetchRequestFromTemplateWithName:substitutionVariables: when you need to use it.
Use the count on the relationship. This pattern will also fit better when integrating the relationship into the UI (for example, number of rows in a table view), and is the method seens in apple's sample code. Creating a count attribute would most likely just add unnecessary complexity to your model.

Load automatically entity of core data relationship

I have two entities A and B between which there is a 1 to n relationship (A-1---n->B). What I want to achieve is that whenever an entity A is recovered is also be automatically retrieved a specific entity B belonging to the relationship. I could think of is to create a subclass of NSManagedObject and modify it to achieve my goal but I do not know how to do that and whether it is the right solution.
You can get XCode to automatically generate an NSManagedObect subclass for you by going to the Editor drop down menu. Once you've generated the subclass, you can write any custom code into the generated subclass but it's often recommended to create a Category as if you need to regenerate the subclass it will wipe said custom code.
As for the retrieving of a specific entity B, you could have another relationship to entity B but this time just a 1 to 1 relationship (say "specialRelationship" for example) and tick the "transient" box (this just means that the data isn't stored in the persistent store, but is determined programmatically). In your Category, you can then write a custom accessor for specialRelationship which will programmatically choose the correct entity B to return.

Core data and sorting after a join condition

I have 3 tables in my core data tables.
Item table: items, which has an ID column and a connection to a properties table.
Properties table: it has a propertyValue column and a connection to item table and a connection to property table.
Property table: it has a propertyName column and a connection to properties table.
The property table contains a propertyName called "price".
The properties table contains a propertyValue "20" for the property "price".
Do you think I can sort the Items table by price?
I am using a NSFetchedResultsController and I am creating a NSFetchRequest for it.
I have tried to write a NSSortDescriptor with a comparator block object for the NSFetchRequest. It isn't working. After this I tried to write a NSSortDescriptor without any selector or block object, I just setup a key called "dealPrice" and created a category on the Item managed object with a method called - (NSString *)dealPrice. It wasn't working neither.
Do you know any other method? Or do you know the solution?
You've obviously got a bad case of SQL fever. Your trying to treat Core Data like an SQL wrapper and that is messing everything up.
Core Data is not SQL. Entities are not tables. Objects are not rows. Attributes are not columns. Relationships are not joins. Core Data is an object graph management system that may or may not persist the object graph and may or may not use SQL far behind the scenes to do so. Trying to think of Core Data in SQL terms will cause you to completely misunderstand Core Data and result in much grief and wasted time.
A Core Data datamodel should not be configured depending on the needs of the UI or any other non-data requirement. Instead, it should accurately model/simulate the real world objects, events or conditions that the app deals with.
In this case, you are modeling:
A type of property that has a name and a price.
An item denoted by an id of some kind
A relationship between one or more particular property instances and one or more instances of item.
Therefore, your data model only needs two entities connected by a relationship. You don't need a "join" because the relationship handles the connection between the two entities automatically.
The simplest model has just a one-to-one relationship:
Item{
id:string
property<-->Property.item
}
Property{
name:string
price:number
item<-->Item.property
}
If each Item object can have several associated Property objects then you would have:
Item{
id:string
properties<-->>Property.item
}
Property{
name:string
price:number
item<<-->Item.properties
}
If each Property object can have several associated Item objects:
Item{
id:string
property<<-->Property.items
}
Property{
name:string
price:number
items<-->>Item.properties
}
How you configure your sort descriptors depends on the details of the relationships and which entity's objects your tableview will display.
What I would first recommend is to stop thinking about CoreData like a database. It is NOT a database. The things you call "tables" are actually Entities. Think of them as objects, that have properties and relationships to other objects. Think about making your data model as simple as possible. Do not try to optimize your structure for database performance etc. The actual backing schema is not under your control.
With that in mind, from what you've posted about your data model, it seems like you should be able to collapse into at least 2 entities instead of 3 (perhaps 1 but not sure without seeing your entire data model). Then, you should be able to do a simple fetch on the Items entity with a predicate that sorts on a property of it's related object.
It sounds like your real object model is and entity named Deal with an attribute named "price".

Resources