核心数据:同一个对象的多个关系

Posted

技术标签:

【中文标题】核心数据:同一个对象的多个关系【英文标题】:Core Data: Multiple relations to same object 【发布时间】:2013-01-11 16:26:27 【问题描述】:

我有一个包含(以及其他)WorkingPlanPosition 的核心数据数据库。 WorkingPlan 有零个或多个 Position 对象。 一切正常,直到我尝试将相同的 Position 添加到一个 WorkingPlan 多次。而不是拥有多个关系(正如我所需要的那样),我只得到一个关系。我可以做些什么来获得与那个Position的多重关系?

【问题讨论】:

Core Data 中的同一个对象不能有多个关系。 (关系的值为NSSet,其中包含一组不同的对象。) 我害怕听到这个。有没有其他方法可以做到这一点? 为什么要多次添加同一个对象?你能解释一下吗? - 如果有帮助,您可以拥有多个具有相同属性的 Position 对象。 这些职位基本上是完成工作计划的步骤。在此过程中,其中一些步骤必须多次执行。不幸的是,数据通过网络服务来自公司的数据库,所以我无法更改任何内容。 我试图在我的答案中找出一些东西。不知道这是否适合您。 【参考方案1】:

正如在 cmets 中已经提到的,Core Data 关系描述了一个对象与一组不同其他对象的关系。一个对象不可能与同一个对象有多个关系。

我想到的一个可能解决方案是在WorkingPlanPosition 之间引入另一个实体WorkingStep

steps 是从WorkingPlanWorkingStep有序 对多关系, plan 是一对一的反比关系, position 是从 WorkingStepPosition 的一对一关系, steps 是一对多的反比关系。

我建议了一个从WorkingPlanWorkingStep有序关系,因为我假设一个计划的步骤必须按照定义的顺序执行。

例如,如果必须按顺序为计划执行位置“pos1”、“pos2”、“pos1”,您将在计划中添加 3 个步骤“step1”、“step2”、“step3” ,并且“step1”和“step3”都与“pos1”相关,“step2”与“pos2”相关。

向有序关系添加值有点棘手。以下代码展示了如何创建上述对象:

WorkingPlan *plan1 = [NSEntityDescription insertNewObjectForEntityForName:@"WorkingPlan" inManagedObjectContext:context];

WorkingStep *step1 = [NSEntityDescription insertNewObjectForEntityForName:@"WorkingStep" inManagedObjectContext:context];
WorkingStep *step2 = [NSEntityDescription insertNewObjectForEntityForName:@"WorkingStep" inManagedObjectContext:context];
WorkingStep *step3 = [NSEntityDescription insertNewObjectForEntityForName:@"WorkingStep" inManagedObjectContext:context];

Position *pos1 = [NSEntityDescription insertNewObjectForEntityForName:@"Position" inManagedObjectContext:context];
Position *pos2 = [NSEntityDescription insertNewObjectForEntityForName:@"Position" inManagedObjectContext:context];

step1.position = pos1;
step2.position = pos2;
step3.position = pos1;

// temporary proxy object used to modify the ordered to-many relationship "steps":
NSMutableOrderedSet *tmpMutableSteps = [plan1 mutableOrderedSetValueForKey:@"steps"];
[tmpMutableSteps addObject:step1];
[tmpMutableSteps addObject:step2];
[tmpMutableSteps addObject:step3];

更多信息:

您也可以像这样在一个“步骤”中设置plan1.steps

plan1.steps = [NSOrderedSet orderedSetWithObjects:step1, step2, step3, nil]; // works!

但某些访问器方法不适用于有序关系:

[plan1 addStepsObject:step1]; // does not work!

似乎是“合乎逻辑的步骤”,但它抛出了NSInvalidArgumentException

*** -[NSSet intersectsSet:]: set argument is not an NSSet

这似乎是自动生成的访问器方法中的一个错误,其他人已经注意到了(例如Exception thrown in NSOrderedSet generated accessors)。使用代理对象是解决该问题的一种解决方法。

【讨论】:

非常好的解决方案,谢谢!我还有一个问题:对于有序关系,我是否必须通过临时对象修改 NSOrderedSet 还是可以直接写信给plan1.steps @cLar:不客气! - 我添加了一些关于如何修改有序关系的信息。 非常感谢您的帮助!【参考方案2】:

在 xCode Core Data 模型中,向 WorkingPlan 添加关系“位置”。在工作计划对象仍处于选中状态并选中“位置”关系的情况下,在数据模型检查器(在 xCode 右侧)的关系属性表单中,选中“复数”“多对多关系”复选框。如果您需要准确的工作计划相关职位数量,请根据需要填写最小/最大计数字段。

【讨论】:

谢谢,但这不是我的意思。我已经将关系设置为“多对多关系”,但我需要多次添加完全相同的对象

以上是关于核心数据:同一个对象的多个关系的主要内容,如果未能解决你的问题,请参考以下文章

将一个对象插入多个关系 - IOS核心数据

如何为对象计数多个关系创建谓词?核心数据 iOS Swift

核心数据关系可以有多个目的地吗?

对象之间的核心数据关系

具有多个映射模型的复杂核心数据迁移

在核心数据中搜索所有具有空“对多”关系的对象