【问题标题】:Cross-model relationships in NSManagedObjectModel from merged models?来自合并模型的 NSManagedObjectModel 中的跨模型关系?
【发布时间】:2010-09-12 22:03:39
【问题描述】:

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

例如,假设模型 1 定义了一个实体 Foo 与关系(一对一)toBar,而模型 2 定义一个实体 Bar 与关系(一对一)toFoo .我将使用-[NSManagedObjectModel mergedModelFromModels] 构建一个 CoreData 堆栈,合并模型 1 和模型 2。有没有办法在数据建模器中或以编程方式定义这些关系,以便它们的行为就像是模型内的关系?

【问题讨论】:

    标签: cocoa macos core-data nsmanagedobject nsmanagedobjectcontext


    【解决方案1】:

    除非toBartoFoo 关系具有目标,否则模型 1 和模型 2 都无法在运行时加载,除非它们格式正确。此外,如果模型 1 和模型 2 具有相同名称的模型,您将无法从它们创建合并模型;它们不会被合并,它们会发生碰撞,这是一个错误。

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

    此外,NS*Description 类都支持userInfo 字典,您可以在 Xcode 的数据建模工具中对其进行编辑,您可以使用该字典将关系的目标标记为替代项。例如,在模型 1 中,您可以有一个 Bar 实体和一个 userInfoMyRealEntity 并在创建合并模型时检查它,作为使用真实实体的信号。

    您还需要为您的替代实体设置替代反向关系;这些将在合并后替换为实数倒数。不过,您不必在所有模型中完全复制您的替代实体;您只需要在实体中的真实模型中使用的反向关系。

    因此,如果您的真实Foo 具有name 属性,而您的真实Bar 具有kind 属性,则您的替代FooBar 不需要这些,只需替代@ 987654337@ 和 toFoo 关系。

    这里有一些代码演示了我在说什么:

    - (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;
    }
    

    这是可行的,因为在 Core Data 中复制 NS*Description 对象是按名称而不是按值相对于关系的目标实体和反向(以及实体的子实体)。因此,虽然模型是可变的——也就是说,在它被设置为 NSPersistentStoreCoordinator 的模型之前——你可以使用这样的技巧将你的模型分解为多个模型。

    【讨论】:

      猜你喜欢
      • 1970-01-01
      • 2020-12-11
      • 1970-01-01
      • 2020-10-27
      • 1970-01-01
      • 2021-10-26
      • 2021-03-26
      • 2013-06-21
      • 1970-01-01
      相关资源
      最近更新 更多