来自合并模型的 NSManagedObjectModel 中的跨模型关系? [英] Cross-model relationships in NSManagedObjectModel from merged models?

查看:22
本文介绍了来自合并模型的 NSManagedObjectModel 中的跨模型关系?的处理方法,对大家解决问题具有一定的参考价值,需要的朋友们下面随着小编来一起学习吧!

问题描述

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

Is it possible to model relationships between entities that are defined in separate NSManagedObjectModels if the entities are always used within an NSManagedObjectModel that is created by merging the relevant models?

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

For example, say model 1 defines an entity Foo with relationship (one-to-one) toBar and that model 2 defines an entity Bar with a relationship (one-to-one) toFoo. I will build a CoreData stack using -[NSManagedObjectModel mergedModelFromModels], merging model 1 and model 2. Is there any way to define these relationships either in the data modeler or programatically so that they behave as if they were in-model relationships?

推荐答案

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

Neither model 1 nor model 2 will be loadable at run time unless they're well-formed — that is, unless the toBar and toFoo relationships have destinations. Furthermore, if model 1 and model 2 have identically-named models, you won't be able to create a merged model from them; they will not be coalesced, they will collide, which is an error.

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

However, you can use the NSManagedObjectModel API manually to load each model and create a new model by hand that contains entities from both. The NSEntityDescription and NSPropertyDescription classes (and its subclasses) do implement the NSCopying protocol so in most cases you should just be able to copy properties over from each component model to your overall model.

此外,NS*Description 类都支持一个 userInfo 字典,你可以在 Xcode 的数据建模工具中编辑它,你可以用它来做一些事情,比如标记目的地作为替身的关系.例如,在模型 1 中,您可以有一个带有 userInfoMyRealEntityBar 实体,并在创建合并模型时检查它,作为表示改用真实实体.

Furthermore, the NS*Description classes all support a userInfo dictionary that you can edit in Xcode's data modeling tool, which you can use to do things like tag the destination of a relationship as a stand-in. For example, in model 1 you could have a Bar entity with a userInfo key MyRealEntity and check for that when creating your merged model, as a signal to use the real entity instead.

您还需要为您的替代实体添加替代反向关系;合并后,这些将被真正的逆替换.不过,您不必在所有模型中完全复制您的替代实体;您只需要实体模型中使用的逆关系.

You'll also want to put stand-in inverse relationships to your stand-in entities; these will be replaced with real inverses after merging. You don't have to totally replicate your stand-in entities in all models, though; you only need the inverse relationships used in your real model in a stand in entity.

因此,如果你真正的 Foo 有一个 name 属性,而你真正的 Bar 有一个 kind 属性,你的替身 FooBar 不需要这些,只是替代 toBartoFoo 关系.

Thus if your real Foo has a name attribute, and your real Bar has a kind attribute, your stand-in Foo and Bar won't need those, just stand-in toBar and toFoo relationships.

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

Here's some code demonstrating what I'm talking about:

- (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 的模型之前——你可以使用这样的技巧将你的模型分解成多个模型.

This works because copying of NS*Description objects in Core Data is by-name rather than by-value with respect to a relationship's destination entity and inverse (and to an entity's subentities as well). Thus while a model is mutable — that is, before it's set as the model for an NSPersistentStoreCoordinator — you can use tricks like this to break your model into multiple models.

这篇关于来自合并模型的 NSManagedObjectModel 中的跨模型关系?的文章就介绍到这了,希望我们推荐的答案对大家有所帮助,也希望大家多多支持IT屋!

查看全文
登录 关闭
扫码关注1秒登录
发送“验证码”获取 | 15天全站免登陆