I have two entities in my model, A and B. A has a to-many relation to B, and its inverse is a to-one relation back to A. I'd like to fetch results of entity B using A as follows:
Perform a fetch request on entity A with some predicate.
On the results returned by this request, drill through to all the related Bs and on these filter by a second predicate.
Return all the valid results of entity B.
Of course I can do (1) and then filter an array of Bs using the second predicate. However I know this is suboptimal.
How can I do this most efficiently, even with a single fetch and predicate?
Unfortunately, I'm not really sure what you are asking. It surely would help if you gave more details.
So, I'll just have to guess... Keep in mind the fetch request can only return one type of entity. So, if you want the thing that is the many side of the relationship, fetch that.
You can use 'dot' notation in your predicate... I'd also probably do the search backwards...
NSFetchRequest *fetchRequest = [NSFetchRequest fetchRequestWithEntityName:#"Employee"];
fetchRequest.predicate = [NSPredicate predicateWithFormat:#"department.name like 'Support'"];
There is 1-to-many relationship from Department to Employee. The above grabs all employees that belong to a department with 'Support' in the name.
If you are already holding an instance of A, just access the related B instances through A's accessor.
If you need to directly fetch all the B's related to a particular A (you don't in this case), you'd build a fetch request for the B entity, with a predicate based on the (inverse) relationship of Bs to A. (The specific syntax will depend on the inverse relationship name, and whether that inverse is a to-one or to-many.)
Related
I have a CoreData Entity named List it has a Relationship to an Entity Address. This is a one-to-many relationship seeing as an Address can be only be one List.
Address entities have an Attribute flag which is an Integer 16.
Is there a way for me to define a Fetched Property in the List entity with a count of all related Address entities that have their flag set to 1? What would the predicate look like?
Thanks
Yes, you can do it like this:
Create a fetch request for the List entity and set its predicate to:
[NSPredicate predicateWithFormat:#"address.flag == %#", #1]
Also don't forget to prefetch relationship so you don't encounter any cache misses.
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.
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.
I have two entities, Issue and User, which I'm using to represent data that comes to me from a server. There's a many-to-many relationship between Issues and Users, and when I get an Issue from the server the object has an array of User IDs.
Later, when I get a User from the server, I want to be able to find the issues that I've stored that have a matching ID.
I had been planning to use a transformable property to store the User IDs for each Issue. However, I've read that transformable properties aren't queryable. Is that true? If so, how do I create an array property that is queryable?
It is correct that you cannot query for entries in an array that is stored as a transformable attribute of the entity.
One possible solution would be to store the list of users IDs as a comma-separated string attribute in the Issue entity, and later search for a matching ID as described here:
Form NSPredicate from string that contains id's.
A different solution would be to create the relationships from Issue to User already in the first pass, when reading and creating the issues. When you get an issue from the server with a list of user IDs, you would find or create the User objects and set the relationship.
Since you are using two entities with many-to-many relationship why don't you implement the relationship using core-data? i.e The usersSet (say) in Issue entity will be an NSSet and the issuesSet in User will be also an NSSet. If thats the case you could implement a predicate in the below way to easily get what you want:
(The below code assumes the to-many relationship between Issue to User is usersSet.)
User *userObjFromServer = <your user object from server>...
NSString *userId = userObjFromServer.userId; //Whichever way you are doing this
NSPredicate *predicate = [NSPredicate predicateWithFormat:#"ANY usersSet.userId like %#",userId];
The queryable array you are talking about will be the relationship (only, its an NSSet).
I have this to-many relationship which contains at least one element:
Appointment <<------>> Invitee
appointment.invitees is an ordered relationship resulting in an NSOrderedSet.
In a table view controlled by a fetched results controller, I have the appointments listed, along with the first element of the invitees set.
Now I want to search this list by invitees' names, using an NSPredicate. But how can refer to the first element of the ordered list in the predicate?
I tried:
fetchRequest.predicate = [NSPredicate predicateWithFormat:
#"invitees[FIRST].lastName CONTAINS[cd] %#", searchTerm];
but I get the unimplemented SQL generation for predicate error. This would make sense, as the result is a collection, but not strictly an array. Still, I think that the sqlite store must be modeling the order, so it should be retrievable.
Any advice?
Clearly, this a question that not even the most expert Core Data savants can answer.
The workaround is to model the first element as a separate to-one relationship and the rest as an optional to-many relationship based on the same related entity.
Appointment <<------> mainInvitee (Invitee)
<<------>> additionalInvitees (Invitee)