Core Data. Join 2 tables with many-tomany relationship? - core-data

I have 2 tables which are linked between themselves with many-to-many relationship.
SQL equivalent doesn't exist because it requires the third table to split a many-to-many relationship to two one-to-many relationships.
For example, I have two core data entities: category with a property (an array of items) and item with a property (an array of categories).
I need to get all the categories except of "empty" categories (when there is no item of this category).
My current temporary solution looks like an incorrect one. I use NSFetchRequest to get all the categories. Then I delete from this array all the categories with an empty item array manually using for-each.

In order to get all categories except the empty ones you could just use a predicate like this:
NSFetchRequest *fetchRequest = [NSFetchRequest fetchRequestWithEntityName:#"Category"];
fetchRequest.predicate = [NSPredicate predicateWithFormat:#"items.#count > 0"];
NSArray *categories = [context executeFetchRequest:fetchRequest error:NULL];

My solution:
[NSPredicate predicateWithFormat:#"ANY items != nil"]

Related

Predicate for fetching children knowing grandchild

I have the following object model in Core Data:
Factory <-->> Division <-->> Department
Entities with relationships:
Factory.divisions_ -> Division.departments_
I'd like to fetch all divisions for factory knowing department but struggle to compose the predicate. The best I have not working:
let factoryPredicate = NSPredicate(format: "SUBQUERY(divisions_, $division, ANY $division.departments == %#).#count > 0", department)
let predicate = NSPredicate(format: "factory IN \(factoryPredicate)")
What I'm missing?
Thank you!

Core Data: Fetching all entity objects having to-many-relationship object with certain value

I have the following relationship in Core Data:
What's the correct NSPredicate to get all courses having at least one student over the age of 25?
[NSPredicate predicateWithFormat:#"ANY students.age > %d", 25]
should work (as predicate for a fetch request for the "Course" entity).

fetching from core data

I am trying to write a fetch routine for data from Core Data. I have managed to fetch all the data in the database and display this in a table view but, how do you fetch only some of the data based on a query?
for example, in SQL:
Select * from DB where name = 'bob';
you'll want to use NSPredicate for that. something along these lines
NSPredicate *predicate = [NSPredicate predicateWithFormat:#"(name == %#)", name];
[fetchRequest setPredicate:predicate];

Core Data Model set up

I have an expense tracking iOS Application using Core Data Model:
Scenario:
-> An abstract parent entity named "Money" with attributes "vendor", "date", "amount" and so on. The two sub-entities "Expense" and "Income" inherit from the parent entity "Money". Then there are other entities such as "Category" and "subCategory" with their attributes. Total as of now: 5 entities (Money, Expense, Income, Category and Subcategory) in my data model.
Question: What I want to achieve is to track expenses daily, per week, bi-weekly, monthly and yearly. I am thinking to make an entity say "Months" with 12 attributes ( Jan - Dec - > month names) but isn't that too much complicated?
Thoughts?
I have a Table-view and using NSFetchedResultsController to fill my table-view with the mix od expenses and Incomes.
You have to create an NSFetchRequest with an NSPredicate that filters for the appropriate time period. Let's say you want to list all expenses between two dates your could implement a method that returns an NSFetchRequest that filters for this period:
- (NSFetchRequest *)filteredFetchRequestForEntity:(NSString *)entityName startDate:(NSDate *)startDate endDate:(NSDate *)endDate
{
NSPredicate *predicate = [NSPredicate predicateWithFormat:#"(date >= %#) AND (date <= %#", startDate, endDate];
NSFetchRequest *fetchRequest = [[NSFetchRequest alloc] init];
NSEntityDescription *entity = [NSEntityDescription entityForName:entityName inManagedObjectContext:self.managedObjectContext];
[fetchRequest setEntity:entity];
[fetchRequest setPredicate:predicate];
return fetchRequest;
}
You could then use this fetchRequest for example in an NSFetchedResultsController
similar to my answer in your other question:
CoreData and TableViews
Then all you'd have to do is create the NSDate objects for start- and endDate for your desired time period and pass them to this method.

How to create a Core Data predicate to test that a relation contains all given objects?

Setup:
I have a Core Data object A that has a to-many relation to B. Call the relation "items". So, a.items returns all B-s associated with A.
Now, I have a manually composed NSSet "itemSet" of B objects.
I want to do the following:
return all A objects whose "items" relation exactly matches itemSet
How do I construct a predicate for that? I’ve tried this:
NSPredicate *predicate = [NSPredicate predicateWithFormat:
#"(ALL items in %#)", itemSet];
But that just gives me Unsupported predicate (null).
This:
NSPredicate *predicate = [NSPredicate predicateWithFormat:
#"(items in %#)", itemSet];
tells me unimplemented SQL generation for predicate. Interesting, but not helpful.
So what’s the right way to filter the relation with a set?
The following predicate could work:
[NSPredicate predicateWithFormat:#"(items.#count == %d) AND (SUBQUERY(items, $x, $x IN %#).#count == %d)",
itemSet.count, itemSet, itemSet.count];
The predicate checks first that the number of items is equal to the size of the given itemSet, and then checks that the number of items which are member of itemSet is also equal to the size of itemSet. If both are true, then items must be equal to itemSet.
Have you tried:
NSPredicate *predicate = [NSPredicate predicateWithFormate:#"items == %#", itemSet];
Alternatively, pull out a subset with a simpler predicate and filter them outside of the fetch request. i.e.
Set a predicate for the number of items in the relationship to the be the same as the number of items in your comparison set.
Fetch the results
Filter these results to show only the ones where the sets contain the same items.

Resources