0
votes

I have a many-to-many relationship between two entities (EntityA and EntityB) in Core Data, and I'm trying to clean up the database periodically by removing instances of EntityB that no longer have any relationships to any instances of EntityA. I'm using Mogenerator to create the .m and .h files, which allows me to reference attribute/relationship names the way I do.

NSPredicate *noRelationPredicate = [NSComparisonPredicate predicateWithLeftExpression:[NSExpression expressionWithFormat:@"%K", EntityBRelationships.relationshipNameForEntityA] rightExpression:[NSExpression expressionWithFormat:@"nil"] modifier:NSDirectPredicateModifier type:NSEqualToPredicateOperatorType options:0];

However, I'm encountering the following error when I perform the fetch: 'NSInvalidArgumentException', reason: 'to-many key not allowed here'

I'd prefer creating the predicate using the class method NSComparisonPredicate predicateWithLeftExpression:rightExpression:modifier:type:options: as I try to avoid string literals in predicate creation.

2

2 Answers

1
votes

You could add a category to entity B that checks if it can be deleted.

-(void)willSave {
    if (!self.aRelations.count && !self.isDeleted) {
        [self.managedObjectContext deleteObject:self];
    }
}

(By using a category in a separate file this code will not be overwritten if you want to re-generate your managed object subclasses.)

0
votes

It's possible to specify what CoreData should do with "orphaned" instances when you define a relationship. See "Relationship Delete Rules" here: https://developer.apple.com/library/mac/documentation/Cocoa/Conceptual/CoreData/Articles/cdRelationships.html#//apple_ref/doc/uid/TP40001857-SW1

In particular, you may be able to use "Cascade" to handle the deletion for you. From the documentation:

Cascade

Delete the objects at the destination of the relationship. For example, if you delete a department, fire all the employees in that department at the same time.