核心数据:同一个对象的多个关系
Posted
技术标签:
【中文标题】核心数据:同一个对象的多个关系【英文标题】:Core Data: Multiple relations to same object 【发布时间】:2013-01-11 16:26:27 【问题描述】:我有一个包含(以及其他)WorkingPlan 和 Position 的核心数据数据库。 WorkingPlan 有零个或多个 Position 对象。 一切正常,直到我尝试将相同的 Position 添加到一个 WorkingPlan 多次。而不是拥有多个关系(正如我所需要的那样),我只得到一个关系。我可以做些什么来获得与那个Position的多重关系?
【问题讨论】:
Core Data 中的同一个对象不能有多个关系。 (关系的值为NSSet
,其中包含一组不同的对象。)
我害怕听到这个。有没有其他方法可以做到这一点?
为什么要多次添加同一个对象?你能解释一下吗? - 如果有帮助,您可以拥有多个具有相同属性的 Position 对象。
这些职位基本上是完成工作计划的步骤。在此过程中,其中一些步骤必须多次执行。不幸的是,数据通过网络服务来自公司的数据库,所以我无法更改任何内容。
我试图在我的答案中找出一些东西。不知道这是否适合您。
【参考方案1】:
正如在 cmets 中已经提到的,Core Data 关系描述了一个对象与一组不同其他对象的关系。一个对象不可能与同一个对象有多个关系。
我想到的一个可能解决方案是在WorkingPlan
和Position
之间引入另一个实体WorkingStep
:
steps
是从WorkingPlan
到WorkingStep
的有序 对多关系,
plan
是一对一的反比关系,
position
是从 WorkingStep
到 Position
的一对一关系,
steps
是一对多的反比关系。
我建议了一个从WorkingPlan
到WorkingStep
的有序关系,因为我假设一个计划的步骤必须按照定义的顺序执行。
例如,如果必须按顺序为计划执行位置“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 右侧)的关系属性表单中,选中“复数”“多对多关系”复选框。如果您需要准确的工作计划相关职位数量,请根据需要填写最小/最大计数字段。
【讨论】:
谢谢,但这不是我的意思。我已经将关系设置为“多对多关系”,但我需要多次添加完全相同的对象。以上是关于核心数据:同一个对象的多个关系的主要内容,如果未能解决你的问题,请参考以下文章