1

I'm building an app that is going to rely on 3 separate .sqlite databases. What methods in my App Delegate am I going to have to edit to allow for this? Right now, my managedObjectContext and managedObjectModel haven't been touched from how the template created them. My persistantStoreCoordinator looks like this:

- (NSPersistentStoreCoordinator *)persistentStoreCoordinator
{
    if (_persistentStoreCoordinator != nil)
    {
        return _persistentStoreCoordinator;
    }

    NSURL *storeURLConfigA = [[self applicationDocumentsDirectory] URLByAppendingPathComponent:@"dbA.sqlite"];
    NSURL *storeURLConfigB = [[self applicationDocumentsDirectory] URLByAppendingPathComponent:@"dbB.sqlite"];
    NSURL *storeURLConfigC = [[self applicationDocumentsDirectory] URLByAppendingPathComponent:@"dbC.sqlite"];

//    // Pre-load .sqlite db in Project Navigator into app on first run after deleting app
    if (![[NSFileManager defaultManager] fileExistsAtPath:[storeURLConfigA path]])
    // dbA
    {
        NSURL *preloadURL = [NSURL fileURLWithPath:[[NSBundle mainBundle] pathForResource:@"dbA" ofType:@"sqlite"]];
        NSError* err = nil;
        if (![[NSFileManager defaultManager] copyItemAtURL:preloadURL toURL:storeURLConfigA error:&err])
        {
            NSLog(@"Error preloading database A - %@",error.description);
        }
    }
    if (![[NSFileManager defaultManager] fileExistsAtPath:[storeURLConfigB path]])
    // dbB
    {
        NSURL *preloadURL = [NSURL fileURLWithPath:[[NSBundle mainBundle] pathForResource:@"dbB" ofType:@"sqlite"]];
        NSError* err = nil;
        if (![[NSFileManager defaultManager] copyItemAtURL:preloadURL toURL:storeURLConfigB error:&err])
        {
            NSLog(@"Error preloading database B - %@",error.description);
        }
    }
    if (![[NSFileManager defaultManager] fileExistsAtPath:[storeURLConfigC path]])
    // dbC
    {
        NSURL *preloadURL = [NSURL fileURLWithPath:[[NSBundle mainBundle] pathForResource:@"dbC" ofType:@"sqlite"]];
        NSError* err = nil;
        if (![[NSFileManager defaultManager] copyItemAtURL:preloadURL toURL:storeURLConfigC error:&err])
        {
            NSLog(@"Error preloading database C - %@",error.description);
        }
    }

//    // Put the Configs into the PersistantStoreCoordinator and tie them to their database file
    NSError *error = nil;
    _persistentStoreCoordinator = [[NSPersistentStoreCoordinator alloc] initWithManagedObjectModel:[self managedObjectModel]];
    NSDictionary *options = @{NSSQLitePragmasOption : @{@"journal_mode": @"DELETE"}};
    if (![_persistentStoreCoordinator addPersistentStoreWithType:NSSQLiteStoreType configuration:@"Config_A" URL:storeURLConfigA options:options error:&error])
    {
        NSLog(@"Error setting up dbA - %@",error.description);
        abort();
    }
    if (![_persistentStoreCoordinator addPersistentStoreWithType:NSSQLiteStoreType configuration:@"Config_B" URL:storeURLConfigB options:options error:&error])
    {
        NSLog(@"Error setting up dbB - %@",error.description);
        abort();
    }
    if (![_persistentStoreCoordinator addPersistentStoreWithType:NSSQLiteStoreType configuration:@"Config_C" URL:storeURLConfigC options:options error:&error])
    {    
        NSLog(@"Error setting up dbC - %@",error.description);
        abort();
    }

    return _persistentStoreCoordinator;
}

Then, I have a single .xcdatamodelID in my mainBundle that has all of my tables/Entities in it, for all three databases. I used XCode's CoreData editor interface to add Configurations Config_A, Config_B, and Config_C, in addition to the Default Configuration. I've moved the Entities into the Configurations for the databases I want them to be in (each Entity should only be in one database).

I run the app and everything runs fine, and I can read and write data without any problem. The problem comes when I view the tables (through the terminal or Firefox's SQLite Manager, for example). All 3 of the databases contain all of the tables, but the tables only have data in the database they are supposed to exist in (there are 0 rows in that table in the other two databases).

Why are all of the tables in each database? How can I get each database to only include the couple tables I want them to have?

4

2 回答 2

2

您已将所有 3 个数据库 (NSPersistentStores) 添加到同一个 NSPersistentStoreCoordinator。因此,当您对托管对象上下文执行保存时,存储协调器会将这些更改分发到其所有存储。相反,为每个数据库创建一个持久存储协调器,也许将它们保存在一个 NSDictionary 中,为 A 数据库持久存储协调器使用键 @"A",为 B 数据库协调器使用键 @"B",等等。然后当你创建一个新的托管对象上下文,您必须确定它属于哪个数据库(NSPersistentStoreCoordinator)。这将允许您将表/更改分开并防止所有数据进入所有 3 个数据库。

于 2013-11-14T21:27:19.493 回答
0

我从 Patrick Goley 的回答开始,但我仍然无法得到我正在寻找的行为。在阅读了他的资料后,我想到了将我的三个数据库分解成完全独立的部分,我能想到的任何地方都可以这样做,这似乎很奏效。如果有人需要我发布我的整个应用程序委托,我会发布,但要点是:

  • 我有 3 NSManagedObjectContexts、3 NSManagedObjectModels 和 3 NSPersistantStoreCoordinators 的属性。

  • 我复制了工厂方法来创建每个方法(最初是在我从模板创建应用程序时编写的)并硬编码每个方法以使用适当的上下文/模型/存储协调器。

  • 我有 3 NSSets 保存其各自数据库的表名,当我想从(或保存到)表中读取时,我传递该表的名称,并使用NSSets 获取适当的上下文/模型/存储协调员。

在花了很多时间阅读我能找到的所有 Apple 文档和其他线程之后,我觉得支持单独的数据库不应该这么困难,但这是迄今为止唯一真正在做我想做的事情。我不知道我以前错过了什么,但这是有效的,所以现在可以了。如果我将来有更多的空闲时间,我可能会更多地研究它并尝试找出正确的方法,如果我找到它,我会更新。

于 2013-11-21T17:31:42.023 回答