我再次阅读了Apple开发人员Core Data文档,发现它在创建SQLLite实体时缺少图形Xcode 4编辑器,就像我在Xcode 3中分离IB时发现它缺乏的那样。
三张桌子:
CrossReference具有ZipData和LocationData的主键,因此我只需要查询CrossReference以获取拉链的所有位置或所有位置的拉链。这当然意味着ZipData和LocationData上的多对多关系(也许还有CrossReference?)。
我所拥有的(不起作用)关系是:
我还没有将任何实体子类化为NSManagedObjects。我只是在viewDidLoad方法中执行下面的代码,只是为了看看我的设置是否有效。
// test/learn the core data frame work
NSManagedObjectContext *context = [self managedObjectContext];
NSManagedObject *locationData = [NSEntityDescription
insertNewObjectForEntityForName:@"LocationData"
inManagedObjectContext:context];
[locationData setValue:@"Testville" forKey:@"City"];
[locationData setValue:@"United Tests" forKey:@"Country"];
[locationData setValue:@"County of Test" forKey:@"County"];
NSManagedObject *zipCodeData = [NSEntityDescription
insertNewObjectForEntityForName:@"ZipCodeData"
inManagedObjectContext:context];
[zipCodeData setValue:[NSNumber numberWithDouble:1111.00] forKey:@"Income"];
[zipCodeData setValue:[NSNumber numberWithDouble:22.00] forKey:@"LandArea"];
[zipCodeData setValue:@"23060" forKey:@"ZipCode"];
NSError *error;
if (![context save:&error]) {
NSLog(@"Whoops, couldn't save: %@", [error localizedDescription]);
}
NSFetchRequest *fetchRequest = [[NSFetchRequest alloc] init];
NSEntityDescription *entity = [NSEntityDescription
entityForName:@"CrossReference" inManagedObjectContext:context];
[fetchRequest setEntity:entity];
NSArray *fetchedObjects = [context executeFetchRequest:fetchRequest error:&error];
for (NSManagedObject *info in fetchedObjects) {
NSLog(@"LocationId: %@", [info valueForKey:@"LocationDataId"]);
NSManagedObject *details = [info valueForKey:@"details"];
NSLog(@"ZipId: %@", [details valueForKey:@"ZipCodeDataId"]);
}
[fetchRequest release];
我不明白如何设置这些关系,并且不确定如何相信主键是以某种方式设置的,而实体只是在一起找到它们的方式。
我在日志中得不到任何东西,即使我查看模拟器sqllite db我看到测试实体已被持久化(但在CrossReference中没有任何内容)。我知道我错过了一些明智的关系,但我不能指责它。
答案 0 :(得分:7)
以下粗体短语显示了您的主要问题:
我再次通读了Apple 开发人员核心数据文档和 发现它缺乏什么 创建时的图形Xcode 4编辑器 正如我发现的那样 SQLLite实体 缺少IB在Xcode中分开的时候 3。
三个表:
ZipData LocationData CrossReference
CrossReference具有 主键 ZipData和LocationData所以我只 需要查询CrossReference来获取 所有拉链的位置或全部 拉链的位置。
没有SQLite entities
这样的东西,Core Data没有表或主键。
核心数据不是SQL。实体不是表格。对象不是行。属性不是列。关系不是联接。核心数据是 对象图管理系统 ,它可能会或可能不会持久保存对象图,并且可能会或可能不会在幕后使用SQL来执行此操作。试图用SQL术语来思考核心数据将导致你完全误解核心数据并导致更多的悲伤和浪费时间。
对于熟练使用SQL的人来说,这是一个常见的错误。您假设Core Data是一个围绕过程SQL的轻量级对象包装器。它不是。 SQLite存储只是四种持久性选项之一,数据模型本身完全独立于您选择的持久性选项,即同一模型适用于所有类型的存储。商店只是存档和解压缩(冷冻干燥和再水化)活动对象图表的不同方式。特定图表如何被持久化是在绝大多数情况下您可以忽略的幕后实现细节。简单地忘记您对SQL的所有了解,因为它无助于您理解Core Data。
这里您的具体问题是您从未设置对象之间的关系。您需要创建一个CrossReference
对象并设置它的关系,因此;
NSManagedObject *crossReference = [NSEntityDescription
insertNewObjectForEntityForName:@"CrossReference"
inManagedObjectContext:context];
[crossReference setValue:locationData forKey:@"location"];
[crossReference setValue:zipCodeData forKey:@"zipCode"];
上下文将确保在相关的LocationData
和ZipData
对象上设置互惠关系。
掌握核心数据的关键是忽略持久性的形式,而只考虑具有属性和关系的对象。一旦你真正内化了这个概念,那么每件事都很容易实现。