如何使用Core Data存储NSSet(一对多)?

时间:2011-07-17 22:53:42

标签: objective-c core-data store nsset

我想知道如何以编程方式更新Core Data对象。该对象是NSSet。所以我可以用下面的方案总结一下:

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

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

Property和Property_has_typology之间存在一对多的关系。由于一个属性可能有几种类型(也就是类别),如Bed&早餐,别墅,酒店,大厦,乡间别墅。

所以我让用户在TableView中选择多行,当他点击保存时,我想存储这些更改。所以我这样做:

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];
}

这种方法有效,但问题是它并没有真正更新现有值。它只是覆盖它。因此,如果我保存相同的两个项目两次(仅作为示例),我会在我的数据库中获得以下内容:

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

所以是的,它们被存储,但它也会创建空行(清除它们而不是删除/更新它们)。

任何帮助将不胜感激。谢谢!

2 个答案:

答案 0 :(得分:0)

//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.

道歉有任何错别字。我现在在我的Windows机器上,所以我无法检查它。

答案 1 :(得分:0)

TechZen说:我刚刚注意到我改变了父母描述的多对多关系。但是,一切都以同样的方式运作。我会在找时间时编辑。

您正在努力通过手动执行Core Data自动执行的操作。要设置关系,只需设置它的一侧,托管对象上下文自动设置另一侧。

所以,如果您有这样的数据模型:

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

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

然后从您刚刚使用的Property对象侧设置关系:

aPropertyObject.typology=aProperty_has_typologyObject;

要设置是否从Property_has_typology对象端使用核心数据为您生成的实现(.m)中的关系访问器方法:

[aProperty_has_typologyObject addPropertiesObject:aPropertyObject];

[aProperty_has_typologyObject addPropertiesObjects:aSetOfPropertyObjects];

......你已经完成了。

如果您必须手动管理所有对象关系,核心数据将无法提供太多实用工具。