开发者

How to store a NSSet (one-to-many) using Core Data?

开发者 https://www.devze.com 2023-03-21 10:23 出处:网络
I am wondering how I can programmatically update a Core Data object. The object is a NSSet though. So I can summarize this with the scheme below:

I am wondering how I can programmatically update a Core Data object. The object is a NSSet though. So I can summarize this with the scheme below:

Property
---------
name
price
typology

Property_has_typology
---------------------
typology_id
property

There is a one-to-many relationship between the Property and Property_has_typology. As one property might have several typologies (aka categories) such as Bed & Breakfast, Villa, Hotel, Mansion, Country House.

So I let the user select multiple rows in my TableView and when he clicks save I want to store these changes. So I do:

NSMutableArray *storeItems = [[NSMutableArray alloc] init];

//Get selected items
for (int i = 0; i < [items count]; i++) {
     Properties_has_typology *typo = [NSEntityDescription insertNewObjectForEntityForName:@"Properties_has_typology" 
                                                                    inManagedObjectContext: [PropertyProvider sharedPropertyProvider].context];
     typo.typology_id = [NSNumber numberWithInt: (int)[items objectAtIndex:i]];
     typo.property = property;
     [storeItems addObject: typo];
}

//Store the items for the Property and save it
if ([storeItems count] > 0) {
    NSLog(@"Going to save...");
    NSSet *storeSet = [[NSSet alloc] initWithArray:storeItems];
    property.typology = storeSet;

    [property save];

    [storeSet release];
}

This kinda works, the issue though is that it doesn't really update the existing values. It just overrides it. So if I save the same two items twice (just as an example) I'd get the开发者_运维技巧 following in my database:

PK  TYPOLOGY
------------
1 | 
2 |   
3 |  4
4 |  6

So yes they are being stored, but it also creates empty rows (clears them instead of deleting/updating them).

Any help would be appreciated. Thanks!


//call 
NSArray* oldTypos = [property.typology allObjects];
[[property removeTypology:[PropertyProvider sharedPropertyProvider].context];
[[property addTypology:storeSet];
for(int i = 0; i < [oldTypos count]; i++){
[[PropertyProvider sharedPropertyProvider].context deleteObject:[oldTypos:objectAtIndex:i]];
}
Error* error = nil;
if(![[PropertyProvider sharedPropertyProvider].context save:&error]){
abort();
}
//Also, rename the to-many relationship to plural.

Apologies of there are any typos. I am on my windows machine at the moment so I cannot check it.


TechZen says: I just noticed after the fact that I reversed the to-many relationship that the parent described. However, everything works the same way. I'll edit when I find time.

You are working to hard by doing things manually that Core Data does automatically. To set a relationship you just set one side of it and the managed object context sets the other automatically.

So, if you have a data model like this:

Property{
    typology<<-->Property_has_typology.properties
}

Property_has_typology{
    properties<-->>Property.typology
}

Then to set the the relationship from the Property object side you just use:

aPropertyObject.typology=aProperty_has_typologyObject;

To set if from the Property_has_typology object side you use the relationship accessor methods in the implementation (.m) that Core Data generated for you:

[aProperty_has_typologyObject addPropertiesObject:aPropertyObject];

or

[aProperty_has_typologyObject addPropertiesObjects:aSetOfPropertyObjects];

... and you are done.

Core Data wouldn't provide much utility if you had to manage all the object relationships by hand.

0

精彩评论

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