One-to-Many NSPredicate Problem in NSFetchedResultsController

Let's say I have a basic data model like this:

Item
Attributes:
name relationship
type
:
properties

Property
Attributes:
name
value
realationships:
item

Each property is associated with one element, and each element is associated with many properties. One property may look exactly like the other.

I know the value of one property and want to get the value of another property from the same elements. So first I get all the properties with this value.

    NSEntityDescription *propEntity = [NSEntityDescription entityForName:@"Property" inManagedObjectContext:self.managedObjectContext];
    NSPredicate *propPredicate = [NSPredicate predicateWithFormat:@"name like 'someName' AND value like %@", value];          
    NSFetchRequest *propRequest = [[NSFetchRequest alloc] init];
    [propRequest setEntity:propEntity];
    [propRequest setPredicate:propPredicate];  
    NSError *error = nil;

    NSArray* properties = [self.managedObjectContext executeFetchRequest:propRequest error:&error];

This works fine, and I get the expected number of objects in my array. So now I want to get all the elements that have these properties:

    NSEntityDescription *itemEntity = [NSEntityDescription entityForName:@"Item" inManagedObjectContext:self.managedObjectContext];
    NSPredicate *itemPredicate = [NSPredicate predicateWithFormat:@"type like %@ AND ANY properties in %@", @"typeValue", properties];          
    NSFetchRequest *itemRequest = [[NSFetchRequest alloc] init];
    [itemRequest setEntity:itemEntity];
    [itemRequest setPredicate:itemPredicate];

    NSArray* items = [self.managedObjectContext executeFetchRequest:itemRequest error:&error];

, . . , :

NSFetchRequest *fetchRequest = [[NSFetchRequest alloc] init];
NSEntityDescription *entity = [NSEntityDescription entityForName:@"Property" inManagedObjectContext:self.managedObjectContext];
[fetchRequest setEntity:entity];
[fetchRequest setFetchBatchSize:20];

NSPredicate *predicate = [NSPredicate predicateWithFormat:@"name like 'someOtherName' AND ANY item in %@", items];

[fetchRequest setPredicate:predicate];

NSSortDescriptor *sortDescriptor = [[NSSortDescriptor alloc] initWithKey:@"value" ascending:YES];
NSArray *sortDescriptors = [[NSArray alloc] initWithObjects:sortDescriptor, nil];

[fetchRequest setSortDescriptors:sortDescriptors];

NSFetchedResultsController *aFetchedResultsController = [[NSFetchedResultsController alloc] initWithFetchRequest:fetchRequest 
                                                                                            managedObjectContext:self.managedObjectContext 
                                                                                            sectionNameKeyPath:@"value"
                                                                                            cacheName:@"Props"];

FetchedResultsController fetchedObjects someOtherName, , , items.

- ?

NSPredicate *predicate = [NSPredicate predicateWithFormat:@"name like 'someOtherName' AND item in %@", items];

NSPredicate *predicate = [NSPredicate predicateWithFormat:@"name like 'someOtherName' AND ALL item in %@", items];

.

, ?

, sql-, , :

Select distinct Property.value from Property where Property.name = 'someOtherName' and property.item in (Select Property.item from Property where Property.name = 'someName' and Property.value = 'someValueIGetFromTheUI')

.

+3
1

, SQL-

/*

SELECT DISTINCT Property.value 
FROM Property 
WHERE Property.name = 'someOtherName' 
AND Property.item IN (SELECT Property.item from Property where Property.name = 'someName' 
                      AND Property.value = 'someValueIGetFromTheUI')
*/

, FRC

NSPredicate *predicate = [NSPredicate predicateWithFormat:@"name == 'someOtherName' AND SUBQUERY(items, $item, $item.name == 'someName' AND $item.value == %@)", value];



NSEntityDescription *propEntity = [NSEntityDescription entityForName:@"Property" inManagedObjectContext:self.managedObjectContext];

NSFetchRequest *fetchRequest = [[NSFetchRequest alloc] init];

[fetchRequest setEntity:propEntity];
[fetchRequest setReturnsDistinctResults:YES];
[fetchRequest setPredicate:predicate]; // from above

NSSortDescriptor *sortDescriptor = [[NSSortDescriptor alloc] initWithKey:@"value" ascending:YES];
NSArray *sortDescriptors = [[NSArray alloc] initWithObjects:sortDescriptor, nil];

[fetchRequest setSortDescriptors:sortDescriptors];

NSFetchedResultsController *aFetchedResultsController = [[NSFetchedResultsController alloc] initWithFetchRequest:fetchRequest managedObjectContext:self.managedObjectContext sectionNameKeyPath:@"value" cacheName:@"Props"];
+1

Source: https://habr.com/ru/post/1764862/


All Articles