开发者

Why CoreData does not provide class named NSDeleteRequest like NSFetchRequest

开发者 https://www.devze.com 2023-03-26 16:05 出处:网络
I was wondering why 开发者_StackOverflowCoreData framework of iPhone does not provide the facility to delete objects from database in a group using NSPredicate. They have provided way to fetch data wi

I was wondering why 开发者_StackOverflowCoreData framework of iPhone does not provide the facility to delete objects from database in a group using NSPredicate. They have provided way to fetch data with NSFetchRequest, but I do not find any method or class to delete the objects in a group with NSPredicate. For example I want to delete those objects from customers table where balance of customer is zero. I can do this with for loop in core data but I wanted to know why the apple has not provided the way to delete objects in this way?


You should be able to delete objects from the database using NSManagedObjectContext's deleteObject: method. Similarly, if you have created .h and .m files from your core data model, it should have created methods for the object to remove one-to-many relationship objects from itself (something similar to -(void)removeCustomersObject:(Customer *)value or -(void)removeCustomers:(NSSet *)value.

Using this information, you should be able to set up a parameter that checks if the balance is zero and removes the objects using one of these methods. One possibility is occasionally using a fetch request to find all customers with a zero balance (using NSPredicate) and removing the fetched results from your database. I hope this helps and gives you an idea where to go. I would have been more detailed, but it's hard to give too much advice without more information. Regardless, this should provide a good stepping stone on how to alleviate your problem.

EDIT: There are two ways to go about deleting multiple objects from your Core Data. The simplest is assuming you have two entities. One is the parent, what I would refer to as MyDatabase, which holds all the children in a one-to-many relationship. These would be your Customer or Person objects. What you name it isn't too important, but those are the objects with a balance. For this example, I will just call the class Customer.

If you generate code for the entities (by going to your xcdatamodeld file, selecting the entities, then go to Editor->Create NSManagedObject Subclass), you will see something like this for the parent entity.

@class Customer;
@interface MyDatabase : NSManagedObject {
}
@property (nonatomic, retain) NSSet *customers;

and in your .m file,

@implementation MyDatabase
@dynamic customers

- (void)addCustomersObject:(Customer *)value {    
    NSSet *changedObjects = [[NSSet alloc] initWithObjects:&value count:1];
    [self willChangeValueForKey:@"customers" withSetMutation:NSKeyValueUnionSetMutation usingObjects:changedObjects];
    [[self primitiveValueForKey:@"customers"] addObject:value];
    [self didChangeValueForKey:@"customers" withSetMutation:NSKeyValueUnionSetMutation usingObjects:changedObjects];
    [changedObjects release];
}

- (void)removeCustomersObject:(Customer *)value {
    NSSet *changedObjects = [[NSSet alloc] initWithObjects:&value count:1];
    [self willChangeValueForKey:@"givenSurveys" withSetMutation:NSKeyValueMinusSetMutation usingObjects:changedObjects];
    [[self primitiveValueForKey:@"customers"] removeObject:value];
    [self didChangeValueForKey:@"customers" withSetMutation:NSKeyValueMinusSetMutation usingObjects:changedObjects];
    [changedObjects release];
}

- (void)addCustomers:(NSSet *)value {    
    [self willChangeValueForKey:@"customers" withSetMutation:NSKeyValueUnionSetMutation usingObjects:value];
    [[self primitiveValueForKey:@"customers"] unionSet:value];
    [self didChangeValueForKey:@"customers" withSetMutation:NSKeyValueUnionSetMutation usingObjects:value];
}

- (void)removeCustomers:(NSSet *)value {
    [self willChangeValueForKey:@"customers" withSetMutation:NSKeyValueMinusSetMutation usingObjects:value];
    [[self primitiveValueForKey:@"customers"] minusSet:value];
    [self didChangeValueForKey:@"customers" withSetMutation:NSKeyValueMinusSetMutation usingObjects:value];
}

Again, these are created for you when the file is created, though if for some reason they aren't, you may not have set up the relationship properly.

To remove the files, you would want to fetch the context using a predicate. The returned request is an NSArray with the objects that match the criteria (a balance of 0). For this example, we'll just call that array objectsToRemove. At this point, we're ready to go about both possible solutions.

1) In this, you don't have a child/parent entity map for your Core Data and just have one entity. In that case, you will use your fetch request as described above. Then you will call something like the following

for (id myObject in objectsToDelete) {
    [self.managedObjectContext deleteObject:myObject];
}
// commit the changes;
NSError *error = nil;
if (![self.managedObjectContext save:&error]) {
    // handle the error;
}

This deletes all the objects, then saves your context once done.

2) If you do have a parent/child Core Data map, it gets easier. In this case, you will simply call the following during your fetch request

[myDatabase removeCustomers:[NSSet setWithArray:objectsToDelete]];
// commit the changes;
NSError *error = nil;
if (![self.managedObjectContext save:&error]) {
    // handle the error;
}

The second approach removes all the objects at once, but does require you have an entity that holds the Customer objects. In my opinion, it's a nicer approach, though not necessary, especially if you don't need to separate Customer objects into different groups. This Core Data tutorial gives an overview of the classic Department and Employees project, which is a very simple, but clear example of how parent/child hierarchies are used in Core Data.

0

精彩评论

暂无评论...
验证码 换一张
取 消

关注公众号