代码之家  ›  专栏  ›  技术社区  ›  Barry Wark

合并模型中NSManagedObjectModel中的跨模型关系?

  •  9
  • Barry Wark  · 技术社区  · 16 年前

    如果实体总是在通过合并相关模型创建的nsmanagedObjectModel中使用,是否可以对在单独nsmanagedObjectModel中定义的实体之间的关系建模?

    例如,假设模型1定义了一个实体 Foo 与关系(一对一) toBar 模型2定义了一个实体 Bar 一对一的关系 toFoo . 我将使用 -[NSManagedObjectModel mergedModelFromModels] ,合并模型1和模型2。是否有任何方法可以在数据建模器中或通过编程来定义这些关系,以便它们的行为就像它们在模型关系中一样?

    1 回复  |  直到 11 年前
        1
  •  16
  •   Chris Hanson    16 年前

    模型1和模型2在运行时都不可加载,除非它们是成形良好的,也就是说,除非 toBar toFoo 关系有目的地。此外,如果模型1和模型2具有相同的命名模型,您将无法从它们创建合并模型;它们将不会合并,它们将发生碰撞,这是一个错误。

    但是,您可以使用 NSManagedObjectModel API手动加载每个模型并手动创建一个新模型,其中包含来自这两个模型的实体。这个 NSEntityDescription NSPropertyDescription 类(及其子类)实现 NSCopying 协议,所以在大多数情况下,您应该能够将属性从每个组件模型复制到整个模型。

    而且, NS*Description 类都支持 userInfo 您可以在Xcode的数据建模工具中编辑的字典,您可以使用它来做一些事情,比如标记关系的目的地作为一个代理。例如,在模型1中,您可以 Bar 实体与A 用户信息 钥匙 MyRealEntity 并在创建合并模型时检查这一点,作为使用实际实体的信号。

    您还需要将代理与代理实体建立反向关系;合并后,这些实体将替换为真正的反向关系。但是,您不必在所有模型中完全复制您的代理实体;您只需要在代理实体中的实际模型中使用反向关系。

    所以如果你真的 Foo 有一个 name 属性,您的实际条具有 kind 属性,你的立场 酒吧 不需要这些,只要站着 托巴尔 豆腐 关系。

    下面是一些演示我所说内容的代码:

    - (NSManagedObjectModel *)mergeModelsReplacingDuplicates:(NSArray *)models {
        NSManagedObjectModel *mergedModel = [[[NSManagedObjectModel alloc] init] autorelease];
    
        // General strategy:  For each model, copy its non-placeholder entities
        // and add them to the merged model. Placeholder entities are identified
        // by a MyRealEntity key in their userInfo (which names their real entity,
        // though their mere existence is sufficient for the merging).
    
        NSMutableArray *mergedModelEntities = [NSMutableArray arrayWithCapacity:0];
    
        for (NSManagedObjectModel *model in models) {
            for (NSEntityDescription *entity in [model entities]) {
                if ([[entity userInfo] objectForKey:@"MyRealEntity"] == nil) {
                    NSEntityDescription *newEntity = [entity copy];
                    [mergedModelEntities addObject:newEntity];
                    [newEntity release];
                } else {
                    // Ignore placeholder.
                }
            }
        }
    
        [mergedModel setEntities:mergedModelEntities];
    
        return mergedModel;
    }
    

    这是因为复制 NS*描述 核心数据中的对象是按名称,而不是按关系的目标实体和反向实体(以及实体的子实体)的值。因此,虽然模型是可变的,也就是说,在它被设置为 NSPersistentStoreCoordinator 您可以使用这样的技巧将您的模型分解为多个模型。