Xcode核心数据关系

时间:2011-06-29 18:15:37

标签: core-data xcode4 relationships

我再次阅读了Apple开发人员Core Data文档,发现它在创建SQLLite实体时缺少图形Xcode 4编辑器,就像我在Xcode 3中分离IB时发现它缺乏的那样。

三张桌子:

  • ZipData
  • LocationData
  • 交叉引用

CrossReference具有ZipData和LocationData的主键,因此我只需要查询CrossReference以获取拉链的所有位置或所有位置的拉链。这当然意味着ZipData和LocationData上的多对多关系(也许还有CrossReference?)。

我所拥有的(不起作用)关系是:

  • ZipData具有指向LocationData的关系“locations”并且是反向的
  • LocationData有一个关系“zipsCodes”,它指向ZipData并且是反向的
  • CrossReference表有两个关系,一个是ZipData(反向),一个是LocationData(反向)。

我还没有将任何实体子类化为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中没有任何内容)。我知道我错过了一些明智的关系,但我不能指责它。

1 个答案:

答案 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"];

上下文将确保在相关的LocationDataZipData对象上设置互惠关系。

掌握核心数据的关键是忽略持久性的形式,而只考虑具有属性和关系的对象。一旦你真正内化了这个概念,那么每件事都很容易实现。