Datos básicos "Upsert" de la base de datos SQLite

Actualmente estoy escribiendo una aplicación que necesita la capacidad de modificar y conservar varios datos. He decidido usar Core Data para este propósito. Cuando el usuario abre la aplicación por primera vez, necesito importar una gran cantidad de datos de una base de datos sqlite, estos datos consisten en las relaciones de muchos a muchos.

Me gustaría encontrar la mejor manera de insertar todos estos datos en mi almacén de datos de código. En este momento estoy usando una NSOperation para realizar la importación, mientras que el resto de la aplicación permanece activa, por lo que el usuario puede hacer otras cosas, pero me gustaría que la importación se realice lo más rápido posible para que se pueda acceder a la aplicación completa de inmediato .

El método que estoy usando ahora es usar un NSFetchRequest para intentar encontrar la entidad relacionada en el almacén de datos, si la entidad está ahí, solo la agrego como una relación, si la entidad no está allí, creo una nueva y Añádelo como una relación. Esto funciona, pero creo que probablemente ni siquiera sea lo óptimo.

El código que estoy usando ahora:

- (void)importEntitiesIntoContext: (NSManagedObjectContext*)managedObjectContext
{
    // Setup the database object
    static NSString* const databaseName = @"DBName.sqlite";
    NSString* databasePath = [[[NSBundle mainBundle] resourcePath] stringByAppendingPathComponent: databaseName];

    sqlite3* database;

    // Open the database from the user's filessytem
    if ( sqlite3_open_v2( [databasePath UTF8String], &database, SQLITE_OPEN_READONLY, NULL ) == SQLITE_OK ) 
    {
        // Setup the SQL Statement
        NSString* sqlStatement = [NSString stringWithFormat: @"SELECT some_columns FROM SomeTable;"];

        sqlite3_stmt* compiledStatement;
        if ( sqlite3_prepare_v2( database, [sqlStatement UTF8String], -1, &compiledStatement, NULL ) == SQLITE_OK ) 
        {
            // Create objects to test for existence of exercises
            NSPredicate* predicate = [NSPredicate predicateWithFormat: @"something == $SOME_NAME"];

            NSEntityDescription* entityDescription = [NSEntityDescription entityForName: @"SomeEntity" 
                                                                 inManagedObjectContext: managedObjectContext];
            NSFetchRequest* fetchRequest = [[[NSFetchRequest alloc] init] autorelease];
            [fetchRequest setEntity: entityDescription];

            // Loop through the results and add them to the feeds array
            while ( sqlite3_step( compiledStatement ) == SQLITE_ROW ) 
            {
                NSString* someName = [NSString stringWithCharsIfNotNull: (char*)sqlite3_column_text( compiledStatement, 1 )];
                NSPredicate* localPredicate = [predicate predicateWithSubstitutionVariables: 
                                               [NSDictionary dictionaryWithObject: someName
                                                                           forKey: @"SOME_NAME"]];
                [fetchRequest setPredicate: localPredicate];

                NSError* fetchError;
                NSArray* array = [managedObjectContext executeFetchRequest: fetchRequest 
                                                                     error: &fetchError];
                if ( array == nil )
                {
                    // handle error
                }
                else if ( [array count] == 0 )
                {
                    SomeEntity* entity = 
                    [NSEntityDescription insertNewObjectForEntityForName: @"SomeEntity"
                                                  inManagedObjectContext: managedObjectContext];
                    entity.name = someName;

// **here I call a method that attempts to add the relationships(listed below)**

                }
                else
                {
                    // Some entity already in store
                }

            }
        }
        else
        {
            NSLog( @"sqlStatement failed: %@", sqlStatement );
        }

        // Release the compiled statement from memory
        sqlite3_finalize( compiledStatement );
    }

    // All the data has been imported into this temporary context, now save it
    NSError *error = nil;
    if ( ![managedObjectContext save: &error] ) 
    {
        NSLog( @"Unable to save %@ - %@", [error localizedDescription] );
    }
}

Método para agregar las relaciones:

- (void)setRelationshipForEntity: (Entity*)entity 
            inManagedObjectContext: (NSManagedObjectContext*)managedObjectContext 
                     usingDatabase: (sqlite3*)database
                        entityId: (NSNumber*)entityId
{

    // Setup the SQL Statement and compile it for faster access
    NSString* sqlStatement = [NSString stringWithFormat: @"SELECT Relationship.name FROM Relationship JOIN Entitys_Relationship ON Entitys_Relationship.id_Relationship = Relationship.id JOIN Entitys ON Entitys_Relationship.id_Entitys = Entitys.id WHERE Entitys.id = %d;", [entityId integerValue]];

    sqlite3_stmt* compiledStatement;
    if ( sqlite3_prepare_v2( database, [sqlStatement UTF8String], -1, &compiledStatement, NULL ) == SQLITE_OK ) 
    {
        // Create objects to test for existence of relationship
        NSPredicate* predicate = [NSPredicate predicateWithFormat: @"relationshipName == $RELATIONSHIP_NAME"];

        NSEntityDescription* entityDescription = [NSEntityDescription entityForName: @"EntityRelationship" 
                                                             inManagedObjectContext: managedObjectContext];
        NSFetchRequest* fetchRequest = [[[NSFetchRequest alloc] init] autorelease];
        [fetchRequest setEntity: entityDescription];

        while ( sqlite3_step( compiledStatement ) == SQLITE_ROW ) 
        {
            NSString* relationshipName = [NSString stringWithCharsIfNotNull: (char*)sqlite3_column_text( compiledStatement, 0 )];
            NSPredicate* localPredicate = [predicate predicateWithSubstitutionVariables: 
                                           [NSDictionary dictionaryWithObject: relationshipName
                                                                       forKey: @"RELATIONSHIP_NAME"]];
            [fetchRequest setPredicate: localPredicate];

            NSError* fetchError;
            NSArray* array = [managedObjectContext executeFetchRequest: fetchRequest 
                                                                 error: &fetchError];
            if ( array == nil )
            {
                // handle error
            }
            else if ( [array count] == 0 )
            {
                EntityRelationship* entityRelationship = 
                [NSEntityDescription insertNewObjectForEntityForName: @"EntityRelationship"
                                              inManagedObjectContext: managedObjectContext];
                entityRelationship.relationshipName = relationshipName;

                [entity addRelationshipObject: entityRelationship];
                //NSLog( @"Inserted relationship named %@", relationshipName );
            }
            else
            {
                [entity addRelationship: [NSSet setWithArray: array]];
            }
        }
    }
    else
    {
        NSLog( @"slqStatement failed: %@", sqlStatement );
    }

    // Release the compiled statement from memory
    sqlite3_finalize( compiledStatement );  
}