核心数据与多个数据库

时间:2013-11-14 18:20:01

标签: ios objective-c core-data

我正在构建一个依赖于3个独立的.sqlite数据库的应用程序。我的App Delegate中有哪些方法可以编辑以允许这样做?目前,我的managedObjectContextmanagedObjectModel尚未触及模板创建方式。我的persistantStoreCoordinator看起来像这样:

- (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;
}

然后,我的mainBundle中有一个单独的.xcdatamodelID,其中包含所有三个数据库中的所有表/实体。除Config_A配置外,我还使用XCode的CoreData编辑器界面添加配置Config_BConfig_CDefault。我已将实体移动到我希望它们所在的数据库的配置中(每个实体应该只在一个数据库中)。

我运行应用程序,一切运行正常,我可以毫无问题地读写数据。当我查看表格时(例如通过终端或Firefox的SQLite Manager),问题就出现了。所有3个数据库都包含所有表,但这些表只包含它们应该存在的数据库中的数据(其他两个数据库中该表中有0行)。

为什么每个数据库中的所有表都是?如何让每个数据库只包含我希望它们拥有的几个表?

2 个答案:

答案 0 :(得分:1)

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

答案 1 :(得分:0)

我从Patrick Goley的回答开始,但我仍然无法得到我想要的行为。在阅读了他所拥有的内容之后,我有了一个想法,就是把我的三个数据库分成完全独立的部分到处都能想到这样做,而这似乎正在起作用。如果有人需要我发布我的整个应用代表,我会,但其主旨是:

  • 我有3 NSManagedObjectContext s,3 NSManagedObjectModel s和3 NSPersistantStoreCoordinator s的属性。

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

  • 我有3个NSSet来保存它各自数据库的表名,当我想读取(或保存到)一个表时,我传递该表的名称,然后使用NSSet以获取适当的上下文/模型/商店协调员。

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

相关问题