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 2record(正确),将其链接为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 的任何Ingredients。如果您删除服务器上的对象,您也需要在本地数据库中删除它。

如果您仍然遇到问题,我建议您在 Recipe 上创建一个类别类,您可以在其中手动查找与名称匹配的任何记录并相应地创建/更新。但是不要忘记删除payload中不存在但本地存在的记录。

【讨论】:

以上是关于magicrecord 删除非导入数据的主要内容,如果未能解决你的问题,请参考以下文章

从 SQL Server 中的 VARCHAR 中删除非数字字符的最快方法

oracle不删除原来的数据库 导入新的数据库

核心数据不持久:使用magicrecord

将数据从aws s3导入mysql或任何非aws数据库

在R中将非矩形数据导入为矩形

cakephp:使用 saveAll(),导入的(非表单相关的)关联数据不保存