我想在核心数据中进行轻量级迁移。我正在为一个运行良好的实体添加一个属性。
但我希望在此特定迁移之后删除实体的数据(该实体表中包含的所有对象)。
我经历了这个question,但这种方法看起来不太好,因为我希望将每个迁移的逻辑分开,这将是将来需要的。
我想到了一种直接重命名该实体但未指定rename Identifier
的方法,以便Core数据将其作为删除实体并添加新实体来处理它,但这件事不会成为永久性的解决未来迁移中的每个类似案例。
如果我可以通过浏览xcdatamodeld
的UI直接删除数据,还是有其他任何方法?
答案 0 :(得分:1)
您可以使用映射模型执行此操作。要创建映射模型,请执行以下步骤:
在XCode中选择新文件
为新文件选择模板:在左侧窗格中选择Core Data,在右侧窗格中选择Mapping Model,然后单击Next
映射模型源数据模型:选择旧数据模型,然后单击“下一步”
映射模型目标数据模型:选择新数据模型,然后单击“下一步”
另存为:您可能知道这是如何工作的
在您的地图模型中,您会在左侧看到名为“ENTITY MAPPINGS”的面板。选择您不想迁移的实体的enity映射,然后键入退格键将其删除。
要使用映射模型自动迁移,您必须使用NSMigratePersistentStoresAutomaticallyOption和NSInferMappingModelAutomaticallyOption选项配置持久性存储协调器。
答案 1 :(得分:0)
简单,轻量级的解决方案,无需修改自动迁移,只需确定是否进行了迁移(例如,通过NSUserDefaults
版本字符串),然后删除所有要删除的实体。
如果没有关系,请考虑NSBatchDeleteRequest
这是非常有效的。但是,在应用程序首次启动迁移后,通过对象图删除也是可行的:获取实体的所有实例并循环结果以删除每个实例,最后保存或批量保存。
如果您需要有关表现的建议,请在评论中回复我。
答案 2 :(得分:0)
经过无奈的寻找方法之后,我能够通过映射模型使用自定义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
很想知道是否有更好的方法/内置的方法来完成此操作。
答案 3 :(得分: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 { }
}
Objective-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