核心数据保存和加载到多个实体

时间:2011-03-11 02:08:59

标签: objective-c core-data entity save

核心数据Noob在这里。

我有一个项目,它将数据保存到单个实体没有问题。但是,因为实体具有太多属性(超过100),所以它会收到警告,我需要对其进行规范化。好的,所以我创建了第二个实体,以双向关系存储更多数据。

问题是,当我尝试保存数据时,数据会保存并重新加载到第一个实体,但不会从第二个实体保存或重新加载。我一定很遗憾。

以下是一些代码:

//ViewDidLoad
    - (void)viewDidLoad
{
    if (managedObjectContext == nil) {
        managedObjectContext = [(CoreDataStuffAppDelegate *) [[UIApplication sharedApplication] delegate] managedObjectContext];
        NSLog(@"After managedObjectContext: %@", managedObjectContext);
    }

   // [self addRecord];
    [super viewDidLoad];

    if ([self fetchData]) {
        NSLog(@"after self fetchData patientArray count is %i", [parentArray count]);
        if ([parentArray count] == 1) {
            Parent *parentInfo = (Parent *)[parentArray objectAtIndex:0];
            parentItem1.text = parentInfo.Mother;
            NSLog(@"fetching on load %i", [parentArray count]);

            //Try 1:  just going after the relationship route (FAIL:  cuz data wont store.  stays null)
         //   childItem1.text = parentInfo.ParentToChild.Kid;

              // Try 2:  going the route of directly talking to the second entity
            childItem1.text = child.Kid;
        }
    }

// Save Record
    - (void)saveRecord{
    if (managedObjectContext == nil) {
        NSLog(@"there is no context, arrg");

    }
    NSLog(@"array count is %i", [parentArray count]);
    if ([parentArray count] == 1) {
        NSManagedObjectContext *context = managedObjectContext;//[parent managedObjectContext];
        NSLog(@"context 1 is: %@", context);

        Parent *parentInfo = (Parent *)[parentArray objectAtIndex:0];
        parentInfo.Mother = parentItem1.text;
        NSLog(@"data says: %@", parentInfo.Mother);
        NSLog(@"text syas: %@", parentItem1.text);

        // Try 1, save it through the child relationship thing.  (failed)
    //    parentInfo.ParentToChild.Kid = childItem1.text;
    //    NSLog(@"childSave says: D: %@ T: %@", parentInfo.ParentToChild.Kid , childItem1.text);

       // Try 2.  from Resipeas app
        if (!child) {
            self.child = [NSEntityDescription insertNewObjectForEntityForName:@"Child" inManagedObjectContext:context];
            [parent addChildObject:child];
            NSLog(@"I hit the child");

        }
        child.Kid = childItem1.text;
        NSLog(@"1: childSave says: D: %@ T: %@", parentInfo.ParentToChild.Kid , childItem1.text);
        NSLog(@"2: childSave says: D: %@ T: %@", child.Kid , childItem1.text);



        NSError *error = nil;
        if (![context save:&error]) {
            NSLog(@"context 2 is: %@", context);
            NSLog(@"major fail %@", [error localizedDescription]);
         //   abort();
        }
    }
    NSLog(@"saving stuff");

}

// FetchData
- (BOOL)fetchData {
    NSLog(@"doing the fetch");
    BOOL returnResult = FALSE;
    NSFetchRequest *fetchRequest = [[NSFetchRequest alloc] init];

    if (managedObjectContext == nil) 
    { 
        NSLog(@"ok making a new managed object context");
        managedObjectContext = [(CoreDataStuffAppDelegate *)[[UIApplication sharedApplication] delegate] managedObjectContext]; 
    }

    NSEntityDescription *entity = [NSEntityDescription entityForName:@"Parent" inManagedObjectContext:managedObjectContext];
    [fetchRequest setEntity:entity];
    [fetchRequest setFetchBatchSize:1];
    NSError *error;
    NSMutableArray *mutableFetchResults = [[managedObjectContext executeFetchRequest:fetchRequest error:&error] mutableCopy];
    if (mutableFetchResults == nil) {
        NSLog(@"Fetching Error");
    } else {
        [self setParentArray:mutableFetchResults];
        returnResult = TRUE;
        NSLog(@"Fetching went well");
    }

    [mutableFetchResults release];
    [fetchRequest release];

    return (returnResult);
}

1 个答案:

答案 0 :(得分:2)

好的,首先,我认为你有一个概念问题,因为我从未见过需要一个具有100个属性的实体。大多数实体都有大约六个属性,我认为我见过的最多的是20左右。

核心数据首先是一个具有持久性的对象图管理系统作为选项。它旨在实现模型 - 视图 - 控制器(MVC)设计的模型层。因此,Core Data主要是关于不存储数据的建模数据。

实体旨在表示一些现实世界的对象,条件或事件。没有很多具有100个属性的真实世界的东西。例如。你想要制作一个人的详细模型。你需要的东西,如名字,姓氏,地址(每个地址组件的属性),驾驶执照#和发行日期,工作地点,地址,社会安全号码等等。如果你试图把所有这些都塞进一个{{ 1}}实体你可以得到几十个属性。但是,如果仔细观察您正在建模的数据和数据中的关系,您会注意到在现实世界中,地址,驾驶执照,工作场所等实际上并不是真人的属性,而是其他真实对象的属性。 与真人相关 。因此,最好的方法是将这些对象的属性分解为单独的实体,并创建与Person实体的关系。这使得模型也更加真实。毕竟,不止一个人可以住在同一个地址或在同一个地方工作。

因此,您可能需要从头开始重新考虑数据模型设计。

确保您了解实体和托管对象之间的区别。实体是抽象的,仅用于为managedObject定义键,值类型和关系。实体是托管对象,因为类是实例。

您还有两个问题:

(1)如果已为实体定义了自定义NSManagedObject子类,则只能使用点语法访问器表单,例如Person。否则,您正在使用通用NSManagedObject实例,并且必须使用键值方法,例如parentInfo.ParentToChild.Kid

(2)fetch仅返回一个实体的对象。因此,如果您有父实体和子实体。每个fetch返回Parent或Child的实例,但从不返回两者(除非它们都从fetch的实体继承。)