Search code examples
core-datarelationshipnsfetchrequestone-to-one

Core Data one-to-one relationship does not work properly


// Test listing all words with their sentence
NSFetchRequest *fetchRequest = [[NSFetchRequest alloc] init];
NSEntityDescription *entity = [NSEntityDescription entityForName:@"Word"
                                          inManagedObjectContext:context];
[fetchRequest setEntity:entity];
[fetchRequest setFetchLimit:10];
NSArray *fetchedObjects = [context executeFetchRequest:fetchRequest error:&error];

 for (Word *info in fetchedObjects) {
     NSLog(@"Word object: %@", info.word);
     Sentence *details = info.relatedToSentence;
     NSLog(@"Sentence object: %@", details.sentence);
 }

I have two entities called Word and Sentence. In each entity there is an attribute called word and sentence, respectively. The relationship is inverse, not optional, and one-to-one.

I am able to extract records from both entities separately, but somehow I can't fetch related objects through one entity, what did I do wrong? The code above works, it is printing out value only for word objects and (null) for sentence objects... I am using sqlite as source for this database. I filled the sqlite file which is created by Xcode after modeling up my model.


Solution

  • For your Core Data model the SQLite tables would look like this:

    CREATE TABLE ZSENTENCE ( Z_PK INTEGER PRIMARY KEY, Z_ENT INTEGER, Z_OPT INTEGER, ZRELATEDTOWORD INTEGER, ZSENTENCE VARCHAR );
    CREATE TABLE ZWORD ( Z_PK INTEGER PRIMARY KEY, Z_ENT INTEGER, Z_OPT INTEGER, ZRELATEDTOSENTENCE INTEGER, ZWORD VARCHAR );
    

    where ZRELATEDTOWORD is the primary key (Z_PK) of the related word, and ZRELATEDTOSENTENCE the primary key of the related sentence. Both have to be filled correctly.

    BUT: Please note that modifying the Core Data SQLite file is not recommended and error-prone. The format is not documented officially and might change in the future.

    I still recommend to write a separate command-line tool (which can use the same Core Data model as your main project) that uses Core Data methods to create and fill the initial database.