My main Entity is called Series. Series has a one to many relationship to an entity called Rounds, connected by one-to-many (ordered), and Rounds has again an NSOrderedSet with Shots. The Shots entity has an attribute called score, which is an Integer.
What I want, is to get all the scores from the Shots entity, belonging to a specific Series.
let shots = currentSeries.rounds.shots as [Shots]
does not give me all the Shots to iterate through, due to the error messeage: "Value of type 'NSOrderedSet' has no member: 'shots'". Somehow, I need to set a predicate to the "Shots" entity which filters all the Shots that belong to a specific "Series" entity.The Series entity does not have a unique identifier, but I guess it could be possible to use the timestamp attribute to isolate a specific "Series". But again, I want all the "Shots" entities, connected to that specifi "Series".
I could seriously need som help about CoreData mining, or at least som suggestions about how to accomplish my efforts.
One way to get all the Shots for a given Series would be to fetch with a predicate:
let fetch = NSFetchRequest(entityName:"Shots")
let fetch.predicate = NSPredicate(format:"rounds.series == %#", currentSeries)
let currentSeriesShots = try! context.executeFetchRequest(fetch) as! [Shots]
(You should add proper error handling). No need to use a unique identifier - CoreData will use its own (internal) identifier for the currentSeries object to determine which Shots to return.
Related
Update: Answered my question by taking advantage of a to-one relationship going the reversed way. Would love to know if there is a way to expand the selection of the fetchRequest to include other entities.
My current fetch request in Swift grabs from the main table, lets call it mainTable, and filters it using an in-between entity, let's call it betweenTable, based on a single object in my third entity, thirdTable. This works. Here's how it's set up.
fetchRequest = FetchRequest<Screen>(entity: mainTable.entity(),
sortDescriptors: [NSSortDescriptor(keyPath: \mainTable.displayName, ascending: true)],
predicate: NSPredicate(format: "betweenTable.thirdTable CONTAINS[cd] %#", selectedThirdItem))
This fetch is based on a condition on the betweenEntity table (a to-many relationship) based on a value on the thirdTable (a to-one relationship). I want to grab a value from the betweenEntity table to use in my list (where the results from this fetch are shown) BUT when I try to index into the between table in the list my build times out. I was hoping there was a way to expand the values selected in the fetch request to include more than just the mainTable entity. For example select mainTable.value, betweenTable.value from ... where...
Can't find any information on this online and was hoping it was possible.
Thanks for any help.
More Information:
mainTable ->> betweenTable is a to-many relationship.
mainTable -> thirdTable is a to-one relationship but to-many reversed.
My main fetch request is for a list that I created as my previous version did live-update and needed to be forced.
Within the list I tried to get the value needed with a mainTable.betweenTable.first(where: ... type expression but then I couldn't build it so I hoped I could add a value in the select for the fetch request. Error: The compiler is unable to type-check this expression in reasonable time; try breaking up the expression into distinct sub-expressions
I had started looking into the NSFetchRequest.IncludesSubentities property but couldn't find anything helpful.
I ended up fixing this by switching my query to grab from the betweenTable entity and then follow the to-one relationship back to the mainTable for display purposes. This way I can display values from both tables. The predicate became a simple predicate: NSPredicate(format: "thirdTable == %#", selectedThirdItem)
I am having a CoreData structure. It is working fine for me. Now I am trying to do an interesting FetchRequest, however I am struggeling to find the correct predicate.
I am having two ententies, Person and Venues. A person can be connected to many venues, but only once to the same venue. And other way around.
I have created a mapping table, which saves the person and venue as relationships. Everything is working fine here. I even implemented the inverse relationship.
In the picture left is my venue. I want to Fetch all persons based on a current venue, where there is NO Mapping created already.
My approach was to use pk_venue, which gives me a set of PersonVenueMapping. However, how can I only use the persons of that Set.
fetch.predicate = NSPredicate(format: "NOT (person IN %#)", venue!.pk_venue[HELP])
I came up with that Predicate. However, how can I access the persons of that set? I would need a array/ set of only the persons, that are connected to that current object.
Edit: Just to give you example.
Person: Max, Leon, Henry
Venue: Venue1, Venue2, Venue 3, Venue 4
PersonVenueMapping: Max <-> Venue1
Now when I select Max, I want Venue2 & Venue3 & Venue4
Thanks in advance
Your model looks very much like a normalised database type model. CoreData is not a database and so some of the requirements of modelling data are more flexible when using it. For instance many to many relationships are possible (and encouraged).
Create your model in this way...
Person
------
name: String
------
assignedVenues: Many relationship to `venue` type
Now every relationship has an inverse property, so...
Venue
------
name: String
------
managers: Many relationship to `Person` type
Now you can go from Max to his assigned venues just by doing...
let selectedPerson = // fetch Max from CoreData
let venues = selectedPerson.assignedVenues
Equally you can go from a venue to find all the people managing it...
let someVenue = // fetch venue from CoreData
let managers = someVenue.managers
To satisfy your question of finding all venues that Max is not managing you can now do a query like...
let selectedPerson = //fetch Max
let predicate = NSPredicate(format:"NONE managers == %#", selectedPerson) // Its been a long time since I did CoreData so forgive me if this syntax isnt correct but the idea is correct. :D
You can now use that predicate to get all venues where max is NOT one of the managers of the venue.
By removing the "mapping" that is required in something like SQLite etc... you can make things much simpler for yourself.
I am confused as to whether you are fetching persons with no mapping to a given venue, or venues with no mapping to a given person. I’ll assume the latter.
Your fetch request will therefore be for the entity Venue. Let’s call the selected Person selectedPerson. The following predicate should return only those Venues that have no mapping to selectedPerson:
NSPredicate(format:”SUBQUERY(pk_venue, $M, $M.person == %#).#count == 0”, selectedPerson)
or in natural language “fetch Venues for which the count of mappings ($M), with person equal to the selected person, is zero”.
I have a one to many relationship User -> Weight as shown on the screenshot. I am able to extract sectioned data from an entity using NSFetchRequest and NSFetchedResultsController and then show it on a Table view with sections.
I am able to extract weight data via the User entity. But my question is, how do I extract that weight data such that I could display it on a table view with sections similar to how NSFetchedResultsController does?
Any help would be appreciated. Thanks in advance!
A NSFetchedResultsController can interact with a collectionView or tableView with its objectAtIndexPath and sections property. But you don't need to use it that way. You can create a NSFetchedResultsController on just the User objects with no sectionNameKeyPath. The number of sections is the the fetchedResultsController number of items. And the number of items in each section is equal to each items's number of weights. likewise when you get the delegated callbacks for changes convert the fetchedResultsController's indexPaths to sections.
Ok, so I figured out the best approach to this. Instead of getting the weight data by querying the User entity, I queried the Weight entity instead and used a predicate to return only the weight data of a specific user.
Something like this:
func requestFetch(ofUser selectedUser: User) -> NSFetchRequest{
...
let userPredicate = NSPredicate(format: "user == %#", selectedUser)
...
return fetchRequest
}
I would really appreciate some help with using NSFetchResultsController.
I think what I am need to do should be simple for some people, but I am a bit stuck!
I will try to explain what I am doing, or a simplified version of it.
I have 2 viewControllers, each displaying an NSTableView. I am using Core Data, with an entity Clubs. One of the viewControllers displays a list of Clubs. So for this one, I create an NSFetchResultsController, passing to it a fetchRequest which is basically NSFetchRequest<Clubs>(entityName: “Clubs”).
Each club has a list of Members, with a one-many relationship). I want to display the members using the 2nd viewController. So when I tap a club in the first table, I want the second table to show its members.
I have an NSFetchResultsController connected to the second table. I am stuck at what fetchRequest to send to it. If I use a similar one to the first, i.e. NSFetchRequest<Members>(entityName: “Members”), as expected, I end up with one table showing all of the clubs stored, and the second table showing ALL members stored, whereas I want only the members in the club selected in the first table. I hope that makes sense. So my question is, what fetchRequest should I send to the 2nd tables NSFetchResultsController?
You should add the following predicate to the fetch request underlying the FRC:
fetchRequest.predicate = NSPredicate(format:"club == %#", theClubSelectedInTheFirstViewController)
I have two entities CIDMPost and CIDMUser. CIDMPost has a one-to-many relationship with CIDMUser named invitees.
Now I have an instance of CIDMPost lets say postObject from where I can easily get the invitees by writing postObject.invitees which will return NSSet.
Now my requirement is I want those invitees (postObject.invitees) as NSFetchedResultsController to show in a UITableView with style Group. Also its need to satisfy the below.
Grouped by invitationStatus (an attribute of CIDMUser)
Order by invitationStatus ASC
Declaration:
I tried few things to fulfil my requirement but got a crashed and the reason was Invalid to many relationship. To know the solution of this crash I posted 'a question' an hour ago. But after few conversation with Daij-Djan I had come to know that the whole process I was trying is wrong.
Just fetch the users in your fetched results controller and apply the sort descriptors as desired filter by invitation with a predicate. Use the status field as the sectionNameKeyPath argument when creating the fetched results controller.
NSPredicate(format: "%# in invitations", post)
where post is the post object to which you want to display the invitees, and invitations is the reverse to-many relationship to the post to which users are invited.
(Note that I am assuming a user can get invited to more than one post, which seems logical. In your problem statement you mention a one-to-many relationship which it seems to me should thus be many-to-many).