首先回复您的评论:
IMO,对于我的用例,加入实体甚至不需要与 Department 有关系。这种一对一是无用的,并且可以由保持相关部门信息的连接实体的属性代替,例如它的 objectID 或其他索引属性来到达它。
这正是部门属性在联接关系中所做的事情。
如果您查看生成的 SQLite 结构,您将看到 Employee 实体和 Department 实体之间的附加映射表,其中仅包含它们的int64
id。
现在,给定的示例是:
例子
在员工/部门典型范例中,如果您有大量员工可以属于多个部门,那么您需要从员工到部门的一对多关系。您不希望反过来,因为每次将员工链接到部门时,都必须加载、更新和保存一个(非常)大的 NSSet。此外,如果从不删除部门实体,则图的完整性很容易维护。可以很容易地实现一个简单的没有逆的一对多关系。
您可以将其视为关系“多”端中对象的另一个属性。
这个例子请求一个一对多的关系:
Employee-->>Department(一个Employee可能属于许多部门)
反之是:
Department-->Employee
因为我们不能实现一个多对多的关系如果没有逆,我们必须实现关系的 to-ONE 端,只是为了确保我们遵守框架的实现。
重申:
根据文档,我们知道如果没有定义反向关系,任何多对多关系都不会持续存在。
==>
因为我们喜欢在没有逆关系的情况下对关系建模,所以我们只将其建模为耦合的 to-ONE 部分(将其建模为对多将违反框架承诺的持久性)
认为它对定义文件夹中的文件(一个文件不能属于多个文件夹),或父子关系。
==>
我们必须将关系定义为:
部门-->员工(这没有多大意义,因为只能容纳一名员工的部门并不是真正的部门)
从另一个角度来看它(否定证明):
假设我们想违背框架并定义一个没有逆的多对多关系。
==>
这意味着我们只会在一个方向上实现它,留下一个 ... 对多关系或 ... MANY-to 关系
==>
这是同一件事不是吗(一对多关系from and entity1 to entity2)
==>
现在,如果我们有一个一对多的关系并且我们选择不实现它的逆,我们可以选择实现对多的部分吗?不,我们不能,这看起来只是多对多关系的一半==>
我们必须实现它的一对多部分。
为了更有意义,我将显示更合乎逻辑的:
Department-->>Employee 所以我们对这种一对多关系的实现将是:
Department<--Employee
这将产生以下 SQLite DB 结构:
ZDEPARTMENT:
Z_PK
Z_ENT
Z_OPT
ZNAME
ZEMPLOYEE:
Z_PK
Z_ENT
Z_OPT
ZDEPARTMENT (int)
ZNAME
我们现在可以在 Department 上定义一个 fetched 属性来获取属于它的所有员工:
employees
谓词:department == $FETCH_SOURCE
您可以在 Department 的方法中强制执行此关系prepareForDeletion
(未测试):(
您将首先userInfo
在 Department 上设置字典以保存强制执行的类型)
(我将“拒绝”规则的实现留给读者:D)
- (void) prepareForDeletion
{
[super prepareForDeletion];
NSEntityDescription* entity = [self entity];
NSDictionary* dict = [entity userInfo] ;
if ([dict count]) {
[dict enumerateKeysAndObjectsUsingBlock:^(NSString* key, NSString* value, BOOL *stop) {
NSArray* arr = [self valueForKey:key];
if( [value isEqualToString:@"cascade"]) {
for (NSManagedObject* obj in arr) {
[[self managedObjectContext] deleteObject:obj];
}
} else if ( [value isEqualToString:@"nullify"] ) {
NSArray* arr = [self valueForKey:key];
for (NSManagedObject* obj in arr) {
[obj setValue:nil forKey:@"department"];
}
}
}];
}
}
正如我所看到的,这就是你对逆向关系所能做的一切。如果您仍然认为您需要多对多关系,请参考我的另一个答案。
问候,
丹。