2

現在、本番環境で使用されているアプリがあります。このアプリのコア データ モデルの次のバージョンに大幅な変更を加えました。

古いデータ モデルから新しいデータ モデルへの大量の変換作業を避けるために、新しいオブジェクト モデルとデータベースの名前を変更しただけで、新しいバージョンのアプリは古いデータベースを参照しなくなりました (これは問題ではありません。古いデータベースのデータは小さく、必要ないためです)。

ただし、古いデータベースから必要なデータが 1 つあります。ユーザーが新しいデータベースに手動で再入力する必要があるのは嫌です。

私の質問: このデータを新しいデータベースに入れるためのオプションは何ですか?

sqlite データベースに対してクエリを実行し、単に新しいデータベースに入ることはできますか? それとも、データをプルするために他の永続ストアとオブジェクト モデルを作成する必要がありますか?

それとも、何かが足りないのですか?

4

3 に答える 3

1

同意します。コア データを使用して古いデータベースに接続し、データを引き出してから新しいデータベースに移動する必要があると思います。完了したら、次のような方法で古いデータベース ファイルを削除する必要があります (注: コア データの結果を SQLite に保存していると想定しています)。

- (NSURL *)urlForDocumentsDirectoryWithFile:(NSString *)fileName {
    NSURL *docPath = [[[NSFileManager defaultManager] URLsForDirectory:NSDocumentDirectory inDomains:NSUserDomainMask] lastObject];
    return [docPath URLByAppendingPathComponent:fileName];
}

- (void)deleteFileFromDocumentsIfExists:(NSString *)fileName {
    NSFileManager *fileManager = [NSFileManager defaultManager];
    NSError *error;
    NSURL *filePath = [self urlForDocumentsDirectoryWithFile:fileName];
    NSLog(@"Deleting file: %@", filePath.absoluteString);
    if ([fileManager fileExistsAtPath:[filePath path]])
    {
        BOOL success = [fileManager removeItemAtURL:filePath error:&error];
        if (!success) NSLog(@"Error: %@", [error localizedDescription]);
    }
}

削除コード:

[self deleteFileFromDocumentsIfExists:@"MyOldDatabaseName.sqlite"];

古いモデルを 1 回しか使用しない場合は、2 つのオブジェクト モデルを使用することについて心配する必要はありません。アプリで「一度だけ使用した」コードを使用するのが無駄であることはわかりますが、Core Data をスキップして手動でクエリを実行する場合でも、これが必要です。

また、コア データのばかげた初期化コードをすべてダンプする DataAccessManager ユニットがあるので、複数のコンテキストに簡単にアクセスできます。共有可能なユニット。

于 2012-11-29T16:17:02.280 に答える
1

ユーザーが更新されたアプリを最初に実行したときに、データを新しいデータベースにコピーするだけでよいようです。その時点で、おそらく古いものを一掃できるので、スペースを無駄に占有しています。それ以上に洗練されたソリューションが必要になるかどうかはわかりません。十分に思えます。

于 2012-11-29T16:08:00.820 に答える
0

上記の両方の提案に感謝します。私は自分の問題を解決するために以下を使用することになりました:

手順:

  • 古いSQLiteデータベースへの接続を試みます。
  • 接続が成功した場合は、レコードを読み取ります。
  • 管理対象オブジェクトコンテキストで新しい管理対象オブジェクトを作成します。
  • 管理対象オブジェクトの値にSQL結果の値を入力します。
  • 管理対象オブジェクトを永続化します。
  • 古いデータベースを削除します。
NSString * dbFilePath = [[self applicationDocumentsDirectoryString] stringByAppendingPathComponent:@ "RPS.sqlite"];

sqlite3*データベース;

if(sqlite3_open([dbFilePath UTF8String]、&database)){
    NSLog(@ "sqlite3_open:failed");
} そうしないと {
    NSString * nsquery = [[NSString alloc] initWithFormat:@ "SELECT * FROM ztable"];
    const char * query = [nsquery UTF8String];

    sqlite3_stmt*ステートメント;
    int prepareCode =(sqlite3_prepare_v2(database、query、-1、&statement、NULL));
    if(prepareCode == SQLITE_OK){
        MyTable * myTableRecord;
        NSLog(@ "データの追加を開始しようとしています");
        while(sqlite3_step(statement)== SQLITE_ROW)
        {{
            NSLog(@ "*****************行が返されました******************");

            myObject = [NSEntityDescription insertNewObjectForEntityForName:@ "myTable" inManagedObjectContext:self.managedObjectContext];

            [myTable setValue:[NSString stringWithFormat:@ "%s"、(char *)sqlite3_column_text(statement、7)] forKey:@ "field1"];
            [myTable setValue:[NSString stringWithFormat:@ "%s"、(char *)sqlite3_column_text(statement、8)] forKey:@ "field2"];

            [自己saveContext];

        }

        sqlite3_finalize(ステートメント);
        NSLog(@ "sqlite3データを追加");
    } そうしないと {
        NSLog(@ "準備コードが正しくありませんでした:%d"、prepareCode);
    }

    NSError * err;
    NSFileManager * filemgr = [[NSFileManager alloc] init];
    [filemgr removeItemAtPath:dbFilePathエラー:&err];
    NSLog(@ "削除された古いsqlite3データベース");
}
于 2012-11-29T18:58:20.363 に答える