轻量级迁移后如何从 Core Data 中删除数据

Posted

技术标签:

【中文标题】轻量级迁移后如何从 Core Data 中删除数据【英文标题】:How to delete data from Core Data after a Lightweight Migration 【发布时间】:2012-06-13 17:20:07 【问题描述】:

在将我的应用程序从 v1 升级到 v2 时,我对核心数据模型进行了一些小改动。这些更改只是为模型添加了新属性。

我已经使用前后更改对数据模型进行了版本化,并在我的 App Delegate 中实现了以下代码:

- (NSPersistentStoreCoordinator *)persistentStoreCoordinator

    if (__persistentStoreCoordinator != nil)
    
        return __persistentStoreCoordinator;
    

    NSURL *storeURL = [[self applicationDocumentsDirectory] URLByAppendingPathComponent:@"ISDEmployees.sqlite"];

    NSLog(@"storeURL:%@",storeURL);

    NSError *error = nil;

    // Create a dictionary for automatic lightweight core data migration
    NSDictionary *options = [NSDictionary dictionaryWithObjectsAndKeys:
                             [NSNumber numberWithBool:YES], NSMigratePersistentStoresAutomaticallyOption,
                             [NSNumber numberWithBool:YES], NSInferMappingModelAutomaticallyOption, 
                             nil];

    __persistentStoreCoordinator = [[NSPersistentStoreCoordinator alloc] initWithManagedObjectModel:[self managedObjectModel]];

    // Set up the persistent store and migrate if needed
    if (![__persistentStoreCoordinator addPersistentStoreWithType:NSSQLiteStoreType configuration:nil URL:storeURL options:options error:&error])
    
        NSLog(@"Unresolved error %@, %@", error, [error userInfo]);
        abort();
    

    return __persistentStoreCoordinator;

基本上是标准的 persistentStoreCoordinator 加上迁移选项。此代码运行良好,我的数据库已成功更新。我遇到的问题是,在数据库更新后,我需要刷新数据库中的所有数据,以便填充新列。我在想我会从相关实体/表中删除数据并强制应用程序重新下载带有添加的列/属性的新数据集。

我不确定如何/在哪里执行删除/更新。一般申请流程是这样的:

通过 Web API 验证登录 登录成功后,调用API获取最新添加/更新的记录。 显示更新的数据

我知道我可以通过将此代码添加到 persistentStoreCoordinator 来检查是否需要迁移:

// Get the current data store meta data
BOOL migrationNeeded = NO;
NSDictionary *existingStoreData = [NSPersistentStoreCoordinator metadataForPersistentStoreOfType:NSSQLiteStoreType URL:storeURL error:&error];

if (existingStoreData) 

    // Check to see if new model is not the same as the existing mode, meaning a migration is required
    if (![self.managedObjectModel isConfiguration:nil compatibleWithStoreMetadata:existingStoreData]) 
    
        migrationNeeded = YES;
    

任何帮助将不胜感激!

更新 #1:

根据以下反馈,我进行了以下更改:

在 AppDelegate 上将 migrationNeeded 从本地更改为公共类变量。 在登录视图中,我添加了以下方法:

- (void)checkForDatabaseMigration

    // Get a copy of the managed object context. If a migration is needed, it will kick it off
    NSManagedObjectContext *managedObjectContext = [(AppDelegate *)[[UIApplication sharedApplication] delegate] managedObjectContext];

    if ([(AppDelegate *)[[UIApplication sharedApplication] delegate] migrationNeeded]) 
    
        // Delete all data from the table
    

    managedObjectContext = nil;

这看起来对吗?代码有效,迁移后数据被删除并插入新副本。我只是讨厌在每次应用程序启动时检查迁移。

【问题讨论】:

【参考方案1】:

如果您知道如何确定何时删除旧数据,您只需获取所需的所有实体并删除它们即可。以下是您执行此操作的方法(例如,如果您想删除所有 Man 实体):

    NSFetchRequest * request = [[NSFetchRequest alloc] init];
[request setEntity:[NSEntityDescription entityForName:@"Man" inManagedObjectContext:myContext]];
[request setIncludesPropertyValues:NO]; //only fetch the managedObjectID

NSError * error = nil;
NSArray * men = [myContext executeFetchRequest:request error:&error];
//error handling goes here
for (NSManagedObject * man in men) 
  [myContext deleteObject:man];

NSError *saveError = nil;
[myContext save:&saveError];
//more error handling here

【讨论】:

感谢 Nikita,它为我指明了正确的方向。我已经通过问题修改了一个可能的解决方案。

以上是关于轻量级迁移后如何从 Core Data 中删除数据的主要内容,如果未能解决你的问题,请参考以下文章

在 Core Data 中进行重量级迁移时尝试迁移 nil 属性值

iOS Core Data - 用于将关系从非可选更改为可选的轻量级迁移

考虑使用 Core Data 轻量级迁移的多个数据模型版本

Core Data轻量级迁移有多少个迁移步骤?

迁移大型 Core Data 数据库崩溃

Core Data(iPhone)实现“自动轻量级迁移”