8

我想在核心数据中进行轻量级迁移。我正在向运行良好的实体添加一个属性。

但我希望在此特定迁移之后删除该实体的数据(该实体表中包含的所有对象)。

我经历了这个问题,但是这种方法看起来并不好,因为我想将将来需要的每个迁移的逻辑分开。

我想到了一种直接重命名该实体但未指定的方法,rename Identifier以便核心数据将其处理为删除实体和添加新实体,但这不会成为未来迁移中每个类似情况的永久解决方案.

如果我可以通过 UI 直接删除数据,xcdatamodeld有什么办法吗?或者还有其他方法吗?

4

4 回答 4

6

在找到一种方法后,我能够做到这一点,EntityMigrationPolicy通过映射模型使用自定义,为实体映射设置自定义策略,例如。EntityNameToEntityName, 本政策 ( ProductName.DeleteEntityPolicy):

// Swift 5
class DeleteEntityPolicy: NSEntityMigrationPolicy {
    override func begin(_ mapping: NSEntityMapping, with manager: NSMigrationManager) throws {
        // Get all current entities and delete them before mapping begins
        let entityName = "EntityName"
        let request = NSFetchRequest<NSManagedObject>(entityName: entityName)
        let context = manager.sourceContext
        let results = try context.fetch(request)
        results.forEach(context.delete)
        try super.begin(mapping, with: manager)
    }
}

有关使用映射模型设置自定义迁移的方法的更多信息:https ://stackoverflow.com/a/40662940

很想知道是否有更好的方法/内置方法来做到这一点。

于 2019-06-12T02:08:27.153 回答
2

您可以使用映射模型来做到这一点。要创建映射模型,请执行以下步骤:

在 XCode 中选择新文件

为您的新文件选择一个模板:在左侧窗格中选择 Core Data,在右侧窗格中选择 Mapping Model,然后单击 Next

映射模型源数据模型:选择您的旧数据模型,然后单击下一步

映射模型目标数据模型:选择您的新数据模型,然后单击下一步

另存为:您可能知道这是如何工作的

在您的映射模型中,您会在左侧看到一个名为“实体映射”的面板。选择您不想迁移的实体的实体映射,然后键入退格键将其删除。

要使用映射模型自动迁移,您必须使用 NSMigratePersistentStoresAutomaticallyOption 和 NSInferMappingModelAutomaticallyOption 选项配置 Persistent Store Coordinator。

于 2015-10-09T16:29:15.140 回答
0

无需修改自动迁移的简单、“轻量级”解决方案只是确定是否发生了迁移(例如通过NSUserDefaults版本字符串),然后删除您想要删除的所有实体。

如果没有关系,考虑NSBatchDeleteRequest哪个是真正有效的。但是,在迁移后首次启动应用程序后,通过对象图删除也是可行的:获取实体的所有实例并遍历结果以删除每个实例,最后或批量保存。

如果您需要有关性能的建议,请在评论中回复我。

于 2015-10-09T23:04:30.040 回答
0

我发现了一种更简单的方法来跳过特定实体的迁移,而无需从映射模型中删除映射(如果实体之间存在复杂的关系,这可能会导致映射模型无效)。

这个想法是一个什么都不做并成功验证迁移步骤的迁移策略:

迅速:

import CoreData

final class DeleteEntityMigrationPolicy: NSEntityMigrationPolicy {
    override func createDestinationInstances(forSource sInstance: NSManagedObject,
                                             in mapping: NSEntityMapping,
                                             manager: NSMigrationManager) throws { }
    
    override func createRelationships(forDestination dInstance: NSManagedObject,
                                      in mapping: NSEntityMapping,
                                      manager: NSMigrationManager) throws { }
    
    override func performCustomValidation(forMapping mapping: NSEntityMapping,
                                          manager: NSMigrationManager) throws { }
}

目标-C:

// DSDeleteEntityMigrationPolicy.h

#import <CoreData/CoreData.h>

@interface DSDeleteEntityMigrationPolicy : NSEntityMigrationPolicy

@end

// DSDeleteEntityMigrationPolicy.m

#import "DSDeleteEntityMigrationPolicy.h"

@implementation DSDeleteEntityMigrationPolicy

- (BOOL)createDestinationInstancesForSourceInstance:(NSManagedObject *)sInstance
                                      entityMapping:(NSEntityMapping *)mapping
                                            manager:(NSMigrationManager *)manager
                                              error:(NSError *__autoreleasing  _Nullable *)error {
    return YES;
}

- (BOOL)createRelationshipsForDestinationInstance:(NSManagedObject *)dInstance
                                    entityMapping:(NSEntityMapping *)mapping
                                          manager:(NSMigrationManager *)manager
                                            error:(NSError *__autoreleasing  _Nullable *)error {
    return YES;
}

- (BOOL)performCustomValidationForEntityMapping:(NSEntityMapping *)mapping
                                        manager:(NSMigrationManager *)manager
                                          error:(NSError *__autoreleasing  _Nullable *)error {
    return YES;
}

@end

于 2020-08-27T09:13:46.060 回答