magicrecord 删除非导入数据
Posted
技术标签:
【中文标题】magicrecord 删除非导入数据【英文标题】:magicalrecord deleting non-imported data 【发布时间】:2012-06-18 12:32:05 【问题描述】:想象一下CoreData中的以下关系
Recipe < --- >> Ingredient
我正在使用 MagicalRecord 定期将服务器数据库 (JSON API) 与我的本地 CoreData 数据库一起导入。
所以,如果我像这样使用Ingredient 1
导入Recipe 1
:
id:1,
name: "Recipe 1",
ingredients: [
name: 'Ingredient 1'
]
因此,MagicalRecord 创建了两个实体并将它们链接在一起。
服务器更改为以下时出现问题:
id:1,
name: "Recipe 1",
ingredients: [
name: 'Ingredient 2' <-- Notice here
]
MagicalRecord 所做的是创建Ingredient 2
record(正确),将其链接为Recipe 1
(正确)的only 成分。但如果我搜索成分,我会在我的 CoreData 数据库中找到 2 条记录。
所以问题是,是否可以在导入和删除对象时跟踪“已删除”对象?
【问题讨论】:
【参考方案1】:这里真正的问题是 MagicalRecord 似乎正在导入重复项。这个问题应该已经在最近的更新中解决了,但是,如果您仍然遇到问题,我建议您在 project issues page 上开票
【讨论】:
好吧,我不这么认为。显然,我将同一收件人与不同的成分(成分 2)相关联。所以我只希望“成分 1”实体和关系消失。【参考方案2】:我已经按照这个过程解决了这个问题。
-
对您的核心数据存储运行查询,该查询将返回您对任何给定服务器请求的期望值。查找查询找到的每个对象的所有 objectID,这些对象预计将由服务器返回。
向服务器发出请求并导入数据。
在保存之前,从您刚刚用于导入数据的上下文中获取所有更新的对象。
删除原始 objectID 列表中不在更新后 objectID 列表中的任何对象
这种方法应该为任何给定请求实现所需的行为。请注意,您仍然可能会删除从其他地方引用的记录,因此只有在将来其他请求可以重新创建它们时才使用此方法。
导入代码
NSArray *existingObjectIDs = [self existingObjectIDsForYourQuery];
[MagicalRecord saveWithBlock:^(NSManagedObjectContext *localContext)
[Recipe MR_importFromObject:response inContext:localContext];
NSArray *objectIDs = [[[localContext updatedObjects] allObjects] valueForKey:@"objectID"];
[self deleteLocalObjectsWithObjectIDs:existingObjectIDs excludingImportedObjectIDs:objectIDs];
];
删除代码
- (void)deleteLocalObjectsWithObjectIDs:(NSArray *)existingObjectIDs excludingImportedObjectIDs:(NSArray *)importedObjectIDs
NSMutableArray *objectsToDelete = [NSMutableArray arrayWithArray:existingObjectIDs];
for ( NSManagedObjectID *objectID in importedObjectIDs )
[objectsToDelete removeObject:objectID];
[MagicalRecord saveWithBlockAndWait:^(NSManagedObjectContext *localContext)
for ( NSManagedObjectID *objectID in objectsToDelete )
NSManagedObject *object = [localContext existingObjectWithID:objectID error:nil];
if ( object )
[localContext deleteObject:object];
];
【讨论】:
【参考方案3】:如果这是您用作主键的名称,您不能只更改服务器上的 Ingredient
名称。 MagicalRecord 和 Core Data 不知道更新了哪条记录,它只知道不存在具有该名称的 Ingredient
,它会为您创建一个新记录并映射来自 Recipe
的关系。您必须手动删除本地应用程序数据库中 JSON 有效负载中不存在的所有记录。
考虑以下几点:
您的Ingredient
对象没有主键。您必须让 MagicalRecord 知道哪个键是主键(当不存在“ingredientID”属性时。
您可以通过进入您的核心数据模型并选择Ingredient
实体来执行此操作。接下来,在数据模型检查器的用户信息中添加一个“relatedByAttribute”键,值为“name”。
接下来进入您的Recipe
实体,为Ingredient
选择关系,并在用户字典中为该关系添加一个“relatedByAttribute”键和“name”值。这样,MagicalRecord 现在知道通过“名称”属性查找任何现有的 Ingredient
记录,如果存在,它将映射到现有记录,其他创建一个新实体并将 Recipe
链接到它。
您可以在此处阅读更多信息:http://www.cimgf.com/2012/05/29/importing-data-made-easy/,特别是您感兴趣的“按键相关”部分。
同样,如上所述,您只更新了名称,这意味着您可能应该删除当前Recipe
的任何Ingredient
s。如果您删除服务器上的对象,您也需要在本地数据库中删除它。
如果您仍然遇到问题,我建议您在 Recipe
上创建一个类别类,您可以在其中手动查找与名称匹配的任何记录并相应地创建/更新。但是不要忘记删除payload中不存在但本地存在的记录。
【讨论】:
以上是关于magicrecord 删除非导入数据的主要内容,如果未能解决你的问题,请参考以下文章